Skip to content

[Bug] Nil pointer panic in SubscribeToNewTasksV3 error handling goroutine when primary RPC subscription fails #2293

Description

@Sertug17

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

  1. Start aggregator with a primary RPC endpoint that is unreachable
  2. Fallback RPC endpoint is reachable
  3. SubscribeToNewTasksV3 returns nil, errMain + valid subFallback
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions