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
}
// getSMBInfoView on GitHub (pinned to 265b3a3dec)
Solutions
- Initialize protocolstate before any SMB code runs (InitProtocolState with options)
- Scope each run to its own execution lifecycle instead of reusing IDs across restarts
- In tests, register dialers once in TestMain
- 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
- Do not invoke fingerprint helpers outside an initialized nuclei execution
- Tear down protocol state only after all executions finish
- Keep execution IDs stable within a run; never persist them across restarts
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
- dialers not initialized for %s
- dialers not initialized for %s
- smb connect: %w
- open pipe %q: %w
- dialers not initialized for execution %s
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/bfbf4e927e95c2e1.
Report an issue: GitHub.