projectdiscovery/nuclei · error

dialers not initialized for %s

Error message

dialers not initialized for %s

What it means

Returned by nuclei's net.Open when protocolstate.GetDialersWithId(executionId) returns nil — the per-execution dialer set (fastdialer plus network policy) was never initialized for the executionId in the JS context. Every raw socket the JS runtime opens is routed through these dialers, so without them Open fails before any connection attempt. Dialers are registered by protocolstate.Init(options) keyed on options.ExecutionId.

Source

Thrown at pkg/js/libs/net/net.go:32

	"github.com/projectdiscovery/utils/reader"
)

var (
	defaultTimeout = time.Duration(5) * time.Second
)

// Open opens a new connection to the address with a timeout.
// supported protocols: tcp, udp
// @example
// ```javascript
// const net = require('nuclei/net');
// const conn = net.Open('tcp', 'acme.com:80');
// ```
func Open(ctx context.Context, protocol, address string) (*NetConn, error) {
	executionId := ctx.Value("executionId").(string)
	dialer := protocolstate.GetDialersWithId(executionId)
	if dialer == nil {
		return nil, fmt.Errorf("dialers not initialized for %s", executionId)
	}
	conn, err := dialer.Fastdialer.Dial(ctx, protocol, address)
	if err != nil {
		return nil, err
	}
	return &NetConn{conn: conn, timeout: defaultTimeout}, nil
}

// Open opens a new connection to the address with a timeout.
// supported protocols: tcp, udp
// @example
// ```javascript
// const net = require('nuclei/net');
// const conn = net.OpenTLS('tcp', 'acme.com:443');
// ```
func OpenTLS(ctx context.Context, protocol, address string) (*NetConn, error) {
	config := &tls.Config{InsecureSkipVerify: true, MinVersion: tls.VersionTLS10}
	host, _, _ := net.SplitHostPort(address)

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Run JS through the nuclei engine (CLI / lib/nuclei NewEngine) so protocolstate.Init runs with the right ExecutionId
  2. When embedding, call protocolstate.Init(&types.Options{ExecutionId: id, ...}) before execution and carry the identical id under ctx key 'executionId'
  3. Debug the context: log ctx.Value('executionId') and compare with the initialized id
  4. For pure library tests, init protocolstate in TestMain instead of mocking piecemeal
Defensive patterns

Strategy: validation

Validate before calling

// Go embedder guard
if protocolstate.GetDialersWithId(executionId) == nil {
    _ = protocolstate.Init(&types.Options{ExecutionId: executionId})
}
// then run the JS that calls net.Open

Try / catch

try { const conn = net.Open('tcp', addr); } catch (e) { if (String(e).includes('dialers not initialized')) { log('run this template via the nuclei engine'); return; } throw e; }

Prevention

When it happens

Trigger: Executing require('nuclei/net') code outside the nuclei engine: standalone goja, direct Go calls to net.Open in tests, or an SDK that constructs its own execution context without engine setup. Also any executionId mismatch between the ctx value and the id used at Init.

Common situations: Custom Go runners embedding nuclei libs; unit tests of JS helper code; tooling that extracts and runs nuclei JS snippets; stale contexts reused after execution-id rotation.

Related errors


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