projectdiscovery/nuclei · error
dialers not initialized for %s
Error message
dialers not initialized for %s
What it means
An executionId was found but protocolstate.GetDialersWithId(executionID) returned nil: no fastdialer set is registered for the execution (never initialized, already torn down, or an id mismatch). The HTTP path refuses to fall back to a default dialer, so it fails closed.
Source
Thrown at pkg/js/libs/http/http.go:272
return nil, fmt.Errorf("http: executionId not set")
}
parsed, err := url.Parse(rawURL)
if err != nil {
return nil, fmt.Errorf("http: invalid url: %w", err)
}
if parsed.Scheme == "" || parsed.Host == "" {
return nil, fmt.Errorf("http: url must include scheme and host")
}
host := parsed.Hostname()
if !protocolstate.IsHostAllowed(executionID, host) {
return nil, protocolstate.ErrHostDenied.Msgf(host)
}
dialers := protocolstate.GetDialersWithId(executionID)
if dialers == nil {
return nil, fmt.Errorf("dialers not initialized for %s", executionID)
}
tlsConfig := &tls.Config{
InsecureSkipVerify: true,
MinVersion: tls.VersionTLS10,
Renegotiation: tls.RenegotiateOnceAsClient,
}
if host != "" {
tlsConfig.ServerName = host
}
transport := &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return dialers.Fastdialer.Dial(ctx, network, addr)
},
DialTLSContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return dialers.Fastdialer.DialTLSWithConfig(ctx, network, addr, tlsConfig)View on GitHub (pinned to 265b3a3dec)
Solutions
- Initialize protocolstate dialers for the execution before any request
- Keep Client construction and requests inside a single execution; never cache a Client across scans
- Cancel or await in-flight requests before execution teardown
Example fix
// before: client (and its execution) already torn down when this runs
const resp = client.Get('https://example.com');
// after: create and use the client within one execution
const client = new http.Client();
const resp = client.Get('https://example.com');
// execution ends after the template run, not before Defensive patterns
Strategy: try-catch
Try / catch
try {
const resp = client.Get(url);
} catch (e) {
if (/dialers not initialized/.test(e.message || '')) {
// execution lifecycle bug: create the Client and request inside one live execution
}
} Prevention
- Keep http.Client construction and requests within a single execution
- Do not cache clients or responses across template runs
- In SDK flows, initialize protocolstate before the first request
When it happens
Trigger: SDK/test usage that sets an executionId but skips protocolstate initialization; requests still in flight when the execution's dialers were released; a Client held across execution boundaries.
Common situations: Same lifecycle-mismatch class as the grpc 'dialers not initialized' error: embedded usage bypassing engine init, goroutines outliving the scan, or executions cleaned up while JS callbacks still run.
Related errors
- grpc: dialers not initialized for executionId %q
- http: executionId not set
- goimpacket: no fastdialer registered for executionId %q
- grpc: refusing to dial without executionId
- http: invalid url: %w
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/c5951bf9beb3a6c5.
Report an issue: GitHub.