projectdiscovery/nuclei · error
could not create request: no request in request response
Error message
could not create request: no request in request response
What it means
RequestResponse.BuildRequest() found rr.Request nil. UnmarshalJSON only sets Request when the JSON entry contains a "request" key, so an entry carrying just a "url" leaves it nil. Instead of panicking on the nil dereference, BuildRequest (guarded by sync.Once) records this error and returns it.
Source
Thrown at pkg/input/types/http.go:68
}
if rr.Request != nil {
cloned.Request = rr.Request.Clone()
}
if rr.Response != nil {
cloned.Response = rr.Response.Clone()
}
return cloned
}
// BuildRequest builds a retryablehttp request from the request response
func (rr *RequestResponse) BuildRequest() (*retryablehttp.Request, error) {
rr.once.Do(func() {
// Request is optional: UnmarshalJSON only populates it when a "request"
// key is present, so an entry carrying just a "url" leaves it nil.
// Dereferencing it below would panic with a nil pointer instead of
// surfacing a usable error, taking the whole scan down.
if rr.Request == nil {
rr.reqErr = fmt.Errorf("could not create request: no request in request response")
return
}
urlx := rr.URL.Clone()
var body io.Reader = nil
if rr.Request.Body != "" {
body = strings.NewReader(rr.Request.Body)
}
req, err := retryablehttp.NewRequestFromURL(rr.Request.Method, urlx, body)
if err != nil {
rr.reqErr = fmt.Errorf("could not create request: %s", err)
return
}
rr.Request.Headers.Iterate(func(k, v string) bool {
req.Header.Add(k, v)
return true
})
if req.Header.Get("User-Agent") == "" {
userAgent := useragent.PickRandom()View on GitHub (pinned to 265b3a3dec)
Solutions
- Give every entry a request object: {"url":"https://host/path","request":{"method":"GET","headers":{},"body":""}}
- If you only need URL targets, use plain list mode (-im list or a newline-separated file) instead of a request/response format
- In SDK code, check rr.Request != nil before calling BuildRequest()
Example fix
// before
{"url": "https://example.com/api"}
// after
{"url": "https://example.com/api", "request": {"method": "GET", "headers": {}, "body": ""}} Defensive patterns
Strategy: type-guard
Type guard
func HasRequest(rr *types.RequestResponse) bool {
return rr != nil && rr.Request != nil
}
// usage
if !HasRequest(rr) {
// fill in a default request or skip this entry before BuildRequest()
} Try / catch
Callers of BuildRequest should treat the returned error as 'entry incomplete': either populate rr.Request (e.g. method GET, empty headers) and rebuild on a fresh RequestResponse, or drop the entry and log it. Because the error is cached in sync.Once, retrying BuildRequest on the same object always returns the same error.
Prevention
- Keep URL-only entries in list mode; use request/response JSON only when you carry the full request
- Validate input files once at startup: every object must have both 'url' and 'request'
- When generating JSON from RequestResponse via MarshalJSON, the 'request' key is always emitted — stripping it downstream is what creates this state
When it happens
Trigger: Loading JSON input entries shaped {"url":"https://host/path"} (no "request" object) and then calling BuildRequest() on them, e.g. through the http input provider or fuzzing flow that needs a full request.
Common situations: Hand-written target JSON lists that only carry URLs; pipelines that strip the "request" field to 'simplify' input; mixing list-mode entries into a format that later requires full request-response pairs.
Related errors
- could not create request: %s
- empty input provided for fuzzing
- missing url in request response
- dialers not initialized for execution id: {ExecutionId}
- no input provider found
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/d6571ba36a91cc1c.
Report an issue: GitHub.