projectdiscovery/nuclei · error

dialers not initialized for %s

Error message

dialers not initialized for %s

What it means

collectSMBv2Metadata (used for SMBv2/3 service fingerprinting) dials the target through protocolstate.GetDialersWithId(executionId); a nil dialer means the execution's network state was never initialized or was already disposed. It is the same state bug as in ConnectSMBInfoMode, reached through the metadata-collection path.

Source

Thrown at pkg/js/libs/smb/smb_private.go:27

	"github.com/praetorian-inc/fingerprintx/pkg/plugins"
	"github.com/praetorian-inc/fingerprintx/pkg/plugins/services/smb"
	"github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"
	zgrabsmb "github.com/zmap/zgrab2/lib/smb/smb"
)

type smbInfoDialFunc func(context.Context) (net.Conn, error)

// ==== private helper functions/methods ====

// collectSMBv2Metadata collects metadata for SMBv2 services.
// @memo
func collectSMBv2Metadata(ctx context.Context, executionId string, host string, port int, timeout time.Duration) (*plugins.ServiceSMB, error) {
	if timeout == 0 {
		timeout = 5 * time.Second
	}
	dialer := protocolstate.GetDialersWithId(executionId)
	if dialer == nil {
		return nil, fmt.Errorf("dialers not initialized for %s", executionId)
	}

	conn, err := dialer.Fastdialer.Dial(ctx, "tcp", net.JoinHostPort(host, fmt.Sprintf("%d", port)))
	if err != nil {
		return nil, err
	}
	defer func() {
		_ = conn.Close()
	}()

	metadata, err := smb.DetectSMBv2(conn, timeout)
	if err != nil {
		return nil, err
	}
	return metadata, nil
}

// getSMBInfo

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Initialize protocolstate before any SMB code runs (InitProtocolState with options)
  2. Scope each run to its own execution lifecycle instead of reusing IDs across restarts
  3. In tests, register dialers once in TestMain
  4. If embedding, prefer the documented nuclei SDK entry points which set state up for you
Defensive patterns

Strategy: validation

Validate before calling

if protocolstate.GetDialersWithId(executionId) == nil {
    return fmt.Errorf("engine not initialized; skip fingerprinting")
}

Type guard

func dialersReady(executionId string) bool {
    return protocolstate.GetDialersWithId(executionId) != nil
}

Try / catch

meta, err := collectSMBv2Metadata(ctx, executionId, host, port, timeout)
if err != nil && strings.Contains(err.Error(), "dialers not initialized") {
    return err // environment bug: fail fast rather than marking hosts dead
}

Prevention

When it happens

Trigger: SMB scanning hits a v2/v3-capable port and the code calls collectSMBv2Metadata while dialers for the executionId are absent — library misuse, uninitialized engine, or post-cleanup execution.

Common situations: SDK integrations that spawn their own goja runtimes; concurrent runs where one goroutine tears down shared state; tests that exercise fingerprinting without the dialer fixture.

Related errors


AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15). Data as JSON: /api/errors/bfbf4e927e95c2e1. Report an issue: GitHub.