Summary
When the primary RPC WebSocket subscription fails on startup but the fallback succeeds, the aggregator launches an error-handling goroutine that calls sub.Err() on a nil event.Subscription interface, causing a runtime panic and crashing the aggregator.
Affected File
core/chainio/avs_subscriber.go, lines 76 and 125
Root Cause
SubscribeToNewTasksV3Retryable returns (nil, err) on failure. If errMain != nil but errFallback == nil, the function proceeds to launch the error handling goroutine (since one subscription is still active). Inside that goroutine, the select statement reads from sub.Err() but sub is nil, causing a nil pointer dereference panic.
// Line 76: if this fails, sub == nil
sub, errMain := SubscribeToNewTasksV3Retryable(...)
// Line 119-144: goroutine launched when errFallback == nil
go func() {
for errMain == nil || errFallback == nil {
select {
case err := <-sub.Err(): // PANIC: sub is nil
Reproduction Scenario
- Start aggregator with a primary RPC endpoint that is unreachable
- Fallback RPC endpoint is reachable
SubscribeToNewTasksV3 returns nil, errMain + valid subFallback
- Error-handling goroutine starts →
sub.Err() panics immediately
Fix
Guard sub.Err() with a nil check, or use a closed channel as a sentinel:
var subErrCh <-chan error
if sub != nil {
subErrCh = sub.Err()
}
// same for subFallback
Severity
Critical crashes the aggregator process. Any network blip on the primary RPC
at startup is enough to trigger it.
Summary
When the primary RPC WebSocket subscription fails on startup but the fallback succeeds, the aggregator launches an error-handling goroutine that calls
sub.Err()on a nilevent.Subscriptioninterface, causing a runtime panic and crashing the aggregator.Affected File
core/chainio/avs_subscriber.go, lines 76 and 125Root Cause
SubscribeToNewTasksV3Retryablereturns(nil, err)on failure. IferrMain != nilbuterrFallback == nil, the function proceeds to launch the error handling goroutine (since one subscription is still active). Inside that goroutine, the select statement reads fromsub.Err()butsubis nil, causing a nil pointer dereference panic.Reproduction Scenario
SubscribeToNewTasksV3returnsnil, errMain+ validsubFallbacksub.Err()panics immediatelyFix
Guard
sub.Err()with a nil check, or use a closed channel as a sentinel:Severity
Critical crashes the aggregator process. Any network blip on the primary RPC
at startup is enough to trigger it.