projectdiscovery/nuclei · error
cookie reuse enabled but cookie-jar is nil
Error message
cookie reuse enabled but cookie-jar is nil
What it means
Headless requests reuse session cookies across steps/templates unless the request sets DisableCookie: true, and that reuse requires a jar attached to the input context (input.CookieJar). If cookie reuse is enabled but the jar is nil, nuclei fails fast rather than silently running without session state. The CLI always builds inputs via contextargs constructors that create a jar, so this is essentially an SDK/embedding error.
Source
Thrown at pkg/protocols/headless/request.go:159
defer func() {
_ = instance.Close()
}()
instance.SetInteractsh(request.options.Interactsh)
if _, err := url.Parse(input.MetaInput.Input); err != nil {
request.options.Output.Request(request.options.TemplatePath, input.MetaInput.Input, request.Type().String(), err)
request.options.Progress.IncrementFailedRequestsBy(1)
return errors.Wrap(err, errCouldNotGetHtmlElement)
}
options := &engine.Options{
Timeout: time.Duration(request.options.Options.PageTimeout) * time.Second,
DisableCookie: request.DisableCookie,
Options: request.options.Options,
}
if !options.DisableCookie && input.CookieJar == nil {
return errors.New("cookie reuse enabled but cookie-jar is nil")
}
timeStart := time.Now()
out, page, err := instance.Run(input, request.Steps, payloads, options)
runDuration := time.Since(timeStart)
if err != nil {
request.options.Output.Request(request.options.TemplatePath, input.MetaInput.Input, request.Type().String(), err)
request.options.Progress.IncrementFailedRequestsBy(1)
return errors.Wrap(err, errCouldNotGetHtmlElement)
}
defer page.Close()
page.InteractshURLs = append(interactshURLs, page.InteractshURLs...)
reqLog := instance.GetRequestLog()
navigatedURL := request.getLastNavigationURLWithLog(reqLog) // also known as matchedURL if there is a match
request.options.Output.Request(request.options.TemplatePath, input.MetaInput.Input, request.Type().String(), nil)View on GitHub (pinned to 265b3a3dec)
Solutions
- Build inputs with contextargs.NewWithInput(ctx, targetURL) / NewWithMetaInput — they initialize the cookie jar
- Or attach a jar manually: jar, _ := cookiejar.New(nil); ctx.CookieJar = jar
- If the template does not need sessions, set `disable_cookie: true` on the headless request
Example fix
// before
ctx := &contextargs.Context{MetaInput: &contextargs.MetaInput{Input: url}}
// after
ctx := contextargs.NewWithInput(context.Background(), url) Defensive patterns
Strategy: validation
Validate before calling
ctx := contextargs.NewWithInput(context.Background(), targetURL) // constructor initializes CookieJar
if !request.DisableCookie && ctx.CookieJar == nil {
jar, _ := cookiejar.New(nil)
ctx.CookieJar = jar
} Prevention
- In SDK code, never build contextargs.Context with a raw struct literal — use NewWithInput/NewWithMetaInput
- If a template needs no sessions, set disable_cookie: true explicitly
- Check input.CookieJar != nil before executing headless requests with cookie reuse enabled
When it happens
Trigger: Embedding nuclei (lib/ or SDK) and constructing contextargs.Context with a struct literal or a constructor that skips CookieJar, then executing a headless template with default (enabled) cookie reuse. The CLI's NewWithInput/NewWithMetaInput always allocate a jar, so CLI users normally never see it.
Common situations: SDK users copying older example code that built Context{...} directly; tests creating bare inputs; custom input providers that bypass the provided constructors.
Related errors
- js must be at least 1
- payload concurrency must be at least 1
- input cannot be empty file or folder expected
- Invalid action type: %s
- the chrome browser is not installed
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/e80dfbab5ff8b117.
Report an issue: GitHub.