projectdiscovery/nuclei · error

dialers not initialized for %s

Error message

dialers not initialized for %s

What it means

connectSMBInfoMode in the smb JS library needs a per-execution dialer (fastdialer + network controls) from protocolstate.GetDialersWithId(executionId). This error means the registry returned nil for that execution ID: the nuclei protocol state was never initialized for this run, or was torn down, so there is no dialer to open TCP connections with.

Source

Thrown at pkg/js/libs/smb/smb.go:96

// const smb = require('nuclei/smb');
// const client = new smb.SMBClient();
// const info = client.ConnectSMBInfoMode('acme.com', 445);
// log(to_json(info));
// ```
func (c *SMBClient) ConnectSMBInfoMode(ctx context.Context, host string, port int) (*smb.SMBLog, error) {
	executionId := ctx.Value("executionId").(string)
	return memoizedconnectSMBInfoMode(ctx, executionId, host, port)
}

// @memo
func connectSMBInfoMode(ctx context.Context, executionId string, host string, port int) (*smb.SMBLog, error) {
	if !protocolstate.IsHostAllowed(executionId, host) {
		// host is not valid according to network policy
		return nil, protocolstate.ErrHostDenied.Msgf(host)
	}
	dialer := protocolstate.GetDialersWithId(executionId)
	if dialer == nil {
		return nil, fmt.Errorf("dialers not initialized for %s", executionId)
	}
	address := net.JoinHostPort(host, fmt.Sprintf("%d", port))
	dialSMBInfo := func(ctx context.Context) (net.Conn, error) {
		return dialer.Fastdialer.Dial(ctx, "tcp", address)
	}
	conn, err := dialSMBInfo(ctx)
	if err != nil {
		return nil, err
	}
	// try to get SMBv2/v3 info
	result, err := getSMBInfo(conn, true, false)
	_ = conn.Close() // close regardless of error
	if err == nil {
		updateSMBv1Support(ctx, result, dialSMBInfo)
		return result, nil
	}

	// try to negotiate SMBv1

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Run the script as a code-protocol template inside a normal nuclei scan, where dialers are created automatically
  2. In library/SDK mode, call protocolstate.InitProtocolState with the run's options before executing templates
  3. In unit tests, initialize protocolstate (or a test dialer) in TestMain before invoking the JS lib
  4. Make sure the executionId passed to the function matches the one the engine registered

Example fix

// before (unit test)
client.ConnectSMBInfoMode(ctx, 'dc01', 445) // dialers not initialized for <id>

// after
func TestMain(m *testing.M) {
    _ = protocolstate.InitProtocolState(ctx, options) // registers dialers
    os.Exit(m.Run())
}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure dialers exist for this execution before using the JS lib
if protocolstate.GetDialersWithId(executionId) == nil {
    return fmt.Errorf("protocol state not initialized; cannot scan")
}

Type guard

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

Try / catch

info, err := client.ConnectSMBInfoMode(ctx, host, 445)
if err != nil && strings.Contains(err.Error(), "dialers not initialized") {
    // engine-state bug, not a target problem: fix initialization, do not retry the target
    return err
}

Prevention

When it happens

Trigger: new smb.SMBClient().ConnectSMBInfoMode(host, 445) executed in a JS runtime whose executionId has no dialers: running the library outside a nuclei engine, in a raw unit test without protocolstate.InitProtocolState, or after the engine cleaned up state.

Common situations: Embedding nuclei as a library and invoking code-protocol helpers without initializing protocolstate; tests on pkg/js/libs executed without the engine fixture; re-using a stale executionId captured before a restart.

Related errors


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