projectdiscovery/nuclei · error

could not create flow executor: %s

Error message

could not create flow executor: %s

What it means

In pkg/tmplexec/exec.go (Execute path), nuclei builds a fresh FlowExecutor per target because the flow executor is tightly coupled with executor options and scan context. If flow.NewFlowExecutor returns an error, execution of this template/target stops with 'could not create flow executor: %s'. In practice the only error NewFlowExecutor returns is 'invalid request type %s' — a request whose Type() is not in the flow engine's supported switch.

Source

Thrown at pkg/tmplexec/exec.go:205

				matched.Store(true)
			} else {
				lastMatcherEvent = event
			}
		}
	}
	var errx error

	// Note: this is required for flow executor
	// flow executer is tightly coupled with lot of executor options
	// and map , wg and other types earlier we tried to use (compile once and run multiple times)
	// but it is causing lot of panic and nil pointer dereference issues
	// so in compile step earlier we compile it to validate javascript syntax and other things
	// and while executing we create new instance of flow executor everytime
	if e.options.Flow != "" {
		flowexec, err := flow.NewFlowExecutor(e.requests, ctx, e.options, executed, e.program)
		if err != nil {
			ctx.LogError(err)
			return false, fmt.Errorf("could not create flow executor: %s", err)
		}
		if err := flowexec.Compile(); err != nil {
			ctx.LogError(err)
			return false, err
		}
		errx = flowexec.ExecuteWithResults(ctx)
	} else {
		errx = e.engine.ExecuteWithResults(ctx)
	}
	ctx.LogError(errx)

	if lastMatcherEvent != nil {
		lastMatcherEvent.Lock()
		defer lastMatcherEvent.Unlock()

		lastMatcherEvent.InternalEvent["error"] = getErrorCause(ctx.GenerateErrorMessage())

		writeFailureCallback(lastMatcherEvent, e.options.Options.MatcherStatus)

View on GitHub (pinned to 265b3a3dec)

Solutions

  1. Upgrade nuclei to the latest release so the flow engine's protocol switch matches current template capabilities
  2. Remove `flow:` from the template, or remove the request section whose protocol the flow engine cannot dispatch
  3. Run `nuclei -validate` and verify each protocol section in the template is one of: dns, file, http, offline-http, headless, tcp/network, ssl, websocket, whois, code, javascript
  4. If using the SDK with custom Request implementations, map them to a supported Type() or drop the flow path

Example fix

# before: flow + workflow-style or unsupported section
flow: |
  http() && ssl()
workflow:
  - template: other.yaml

# after: keep flow, move workflow logic into plain templates without flow
Defensive patterns

Strategy: try-catch

Validate before calling

// Before executing a flow template, verify every request type is dispatchable:
func flowDispatchable(reqs []protocols.Request) bool {
    for _, r := range reqs {
        switch r.Type() {
        case templateTypes.DNSProtocol, templateTypes.FileProtocol, templateTypes.HTTPProtocol,
            templateTypes.OfflineHTTPProtocol, templateTypes.HeadlessProtocol, templateTypes.NetworkProtocol,
            templateTypes.SSLProtocol, templateTypes.WebsocketProtocol, templateTypes.WHOISProtocol,
            templateTypes.CodeProtocol, templateTypes.JavascriptProtocol:
        default:
            return false
        }
    }
    return true
}

Try / catch

ok, err := executer.Execute(scanCtx)
if err != nil {
    if strings.Contains(err.Error(), "could not create flow executor") {
        // template/binary protocol-support mismatch: skip template, suggest upgrade
        log.Printf("skipping flow template %s (unsupported request type) — upgrade nuclei", tid)
        continue
    }
    return err
}

Prevention

When it happens

Trigger: A template with a `flow:` block that also contains a request section the flow engine's switch does not handle (WorkflowProtocol or InvalidProtocol types, or a protocol type added in a newer nuclei than the running binary supports). The compile-time check (error 461) only validates JS syntax, so this surfaces later at Execute time on the first target.

Common situations: Version skew: running a new community template with flow against an older nuclei binary whose flow switch lacked a protocol; SDK users assembling custom protocols.Request implementations and enabling options.Flow; editing a template to add an exotic protocol section while keeping `flow:`.

Related errors


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