projectdiscovery/nuclei · error

http: executionId not set

Error message

http: executionId not set

What it means

Client.do found no executionId: neither the goja runtime (c.nj.ExecutionId()) nor the request context carries one. The nuclei/http client routes every dial through the per-execution fastdialer and host policy, so it fails closed when used outside a nuclei scan execution rather than silently using a default dialer.

Source

Thrown at pkg/js/libs/http/http.go:254

	return defaultClient().Request(ctx, method, rawURL, body)
}

func defaultClient() *Client {
	return &Client{
		FollowRedirects: true,
		MaxRedirects:    defaultMaxRedirects,
		TimeoutSeconds:  defaultTimeoutSeconds,
		MaxBodyBytes:    defaultMaxBodyBytes,
		headers:         make(http.Header),
	}
}

func (c *Client) do(ctx context.Context, method, rawURL, body string) (*Response, error) {
	c.init()

	executionID := executionIDFrom(ctx, c)
	if executionID == "" {
		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)

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Run the code as a nuclei code-protocol template so the engine attaches the executionId
  2. From Go/tests, seed the runtime/context exactly like nuclei: context.WithValue(ctx, "executionId", id) plus protocolstate initialization for that id
  3. Do not construct a Client in one runtime and use it in another

Example fix

// before: standalone script/test, no execution bound
const resp = http.Get('https://example.com'); // -> http: executionId not set

// after: run as a nuclei code template (executionId seeded automatically);
// from Go tests, mirror the engine first:
//   ctx = context.WithValue(ctx, "executionId", execID)
//   ... protocolstate init for execID ...
//   const resp = http.Get('https://example.com');
Defensive patterns

Strategy: try-catch

Try / catch

try {
  const resp = http.Get(url);
} catch (e) {
  if (/executionId not set/.test(e.message || '')) {
    // running outside a scan: move the code into a nuclei code template (or seed the runtime from Go)
  }
}

Prevention

When it happens

Trigger: Calling http.Get() or new http.Client().Get() from standalone Go code or tests without seeding an executionId; a runtime not initialized by nuclei's JS compiler; SDK (lib/) usage that drives the JS libraries directly.

Common situations: Embedded nuclei users exercising template logic outside the engine; unit tests invoking the http package without the scan scaffolding; tools that re-host goja runtimes without nuclei's runtime setup.

Related errors


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