projectdiscovery/nuclei · error

dialers not initialized for %s

Error message

dialers not initialized for %s

What it means

Thrown by the memoized MySQL fingerprint function when protocolstate.GetDialersWithId(executionId) returns nil — i.e. no dialer set (fastdialer + network policy) was ever registered for the executionId carried in the JS context. All socket work in the nuclei JS runtime goes through these per-execution dialers, created by protocolstate.Init(options) keyed on options.ExecutionId. Without them, no network call can be made and every mysql.* network API fails immediately.

Source

Thrown at pkg/js/libs/mysql/mysql.go:136

// const mysql = require('nuclei/mysql');
// const info = mysql.FingerprintMySQL('acme.com', 3306);
// log(to_json(info));
// ```
func (c *MySQLClient) FingerprintMySQL(ctx context.Context, host string, port int) (MySQLInfo, error) {
	executionId := ctx.Value("executionId").(string)
	return memoizedfingerprintMySQL(ctx, executionId, host, port)
}

// @memo
func fingerprintMySQL(ctx context.Context, executionId string, host string, port int) (MySQLInfo, error) {
	info := MySQLInfo{}
	if !protocolstate.IsHostAllowed(executionId, host) {
		// host is not valid according to network policy
		return info, protocolstate.ErrHostDenied.Msgf(host)
	}
	dialer := protocolstate.GetDialersWithId(executionId)
	if dialer == nil {
		return MySQLInfo{}, 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 info, err
	}
	defer func() {
		_ = conn.Close()
	}()

	handshake, err := fingerprintConn(conn, mysqlFingerprintTimeout)
	if err != nil {
		return info, err
	}

	info.Host = host
	info.Port = port
	info.Protocol = "mysql"

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Run the scripts through the nuclei engine (CLI or lib/nuclei NewEngine), which calls protocolstate.Init with the matching ExecutionId before executing JS
  2. If embedding manually, call protocolstate.Init(&types.Options{ExecutionId: id, ...}) before any script execution and put the same id into the context under key 'executionId'
  3. Check for executionId mismatch: the ctx value and the Init options must use the identical string
  4. In tests, either init protocolstate or mock at a higher level instead of hitting the real dialer path

Example fix

// before (Go, standalone goja)
ctx := context.WithValue(context.Background(), "executionId", "test-exec")
mysql.IsMySQL(ctx, "acme.com", 3306) // dialers not initialized for test-exec

// after
import "github.com/projectdiscovery/nuclei/v3/pkg/protocols/common/protocolstate"

ctx := context.WithValue(context.Background(), "executionId", "test-exec")
if protocolstate.ShouldInit("test-exec") {
  err := protocolstate.Init(&types.Options{ExecutionId: "test-exec"})
  if err != nil { log.Fatal(err) }
}
mysql.IsMySQL(ctx, "acme.com", 3306)
Defensive patterns

Strategy: validation

Validate before calling

// Go embedder: ensure dialers exist for this execution before running scripts
if protocolstate.ShouldInit(executionId) {
    if err := protocolstate.Init(&types.Options{ExecutionId: executionId /* network policy opts */}); err != nil {
        return fmt.Errorf("init dialers: %w", err)
    }
}

Try / catch

try { mysql.IsMySQL(host, port); } catch (e) { if (String(e).includes('dialers not initialized')) { log('runtime not initialized — run via nuclei engine'); return; } throw e; }

Prevention

When it happens

Trigger: Executing nuclei JS libraries (mysql, net, oracle, pop3, ...) from a context that never ran protocolstate.Init for that executionId: a standalone goja runtime, a Go unit test that calls the exported Go functions directly, or an SDK integration that builds its own execution context instead of using the nuclei engine. Also an executionId in ctx that differs from the one used at Init time.

Common situations: Embedding nuclei libs in Go tests without the lib/nuclei engine; reusing a stale context after the engine rotated execution ids; calling library code from a goroutine where the value of ctx key 'executionId' was overwritten or missing (though then the type assertion panics first); custom runners that skip engine initialization.

Related errors


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