{"record":{"id":"7420c289f8b2f769","repo":"crowdsecurity/crowdsec","slug":"missing-s-header","errorCode":null,"errorMessage":"missing '%s' header","messagePattern":"missing '(.+?)' header","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/appsec/request.go","lineNumber":407,"sourceCode":"\tip := net.ParseIP(host)\n\tif ip == nil {\n\t\tlog.Errorf(\"Invalid appsec remote IP address source %v\", remoteAddr)\n\t\treturn remoteAddr\n\t}\n\treturn ip.String()\n}\n\n// Generate a ParsedRequest from a http.Request. ParsedRequest can be consumed by the App security Engine.\n// bodySettings controls the maximum body size and what to do when the limit is exceeded.\nfunc NewParsedRequestFromRequest(r *http.Request, logger *log.Entry, bodySettings BodySettings) (ParsedRequest, error) {\n\tbody, bodyTruncated, bodySizeExceeded, err := readRequestBody(r, bodySettings, logger)\n\tif err != nil {\n\t\treturn ParsedRequest{}, err\n\t}\n\n\tclientIP := r.Header.Get(IPHeaderName)\n\tif clientIP == \"\" {\n\t\treturn ParsedRequest{}, fmt.Errorf(\"missing '%s' header\", IPHeaderName)\n\t}\n\n\tclientURI := r.Header.Get(URIHeaderName)\n\tif clientURI == \"\" {\n\t\treturn ParsedRequest{}, fmt.Errorf(\"missing '%s' header\", URIHeaderName)\n\t}\n\n\tclientMethod := r.Header.Get(VerbHeaderName)\n\tif clientMethod == \"\" {\n\t\treturn ParsedRequest{}, fmt.Errorf(\"missing '%s' header\", VerbHeaderName)\n\t}\n\n\tclientHost := r.Header.Get(HostHeaderName)\n\tif clientHost == \"\" {\n\t\tlogger.Debugf(\"missing '%s' header\", HostHeaderName)\n\t}\n\n\tuserAgent := r.Header.Get(UserAgentHeaderName)","sourceCodeStart":389,"sourceCodeEnd":425,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/request.go#L389-L425","documentation":"NewParsedRequestFromRequest builds a ParsedRequest from the internal HTTP request the bouncer forwards, which must carry X-Crowdsec-Appsec-IP (IPHeaderName) identifying the original client. This error means that required header is absent, so the client IP is unknown and the request cannot be evaluated.","triggerScenarios":"appsecHandler (or tests) calls NewParsedRequestFromRequest on a request whose IPHeaderName header is missing or empty — usually a misconfigured bouncer or a direct request hitting the appsec endpoint bypassing the bouncer.","commonSituations":"Bouncer not configured to forward X-Crowdsec-Appsec-* headers, older bouncer version predating the header set, direct curl/browser access to the appsec port, or a proxy stripping custom headers.","solutions":["Update/configure your bouncer to send the X-Crowdsec-Appsec-IP header on forwarded requests","Verify no proxy in between strips X-Crowdsec-* headers","Ensure requests reach the appsec endpoint only via the bouncer, not directly","Check bouncer/crowdsec version compatibility (appsec header protocol)"],"exampleFix":"// bouncer side: before\nreq, _ := http.NewRequest(\"POST\", appsecURL, body)\n// after\nreq.Header.Set(\"X-Crowdsec-Appsec-IP\", clientIP)\nreq.Header.Set(\"X-Crowdsec-Appsec-URI\", uri)\nreq.Header.Set(\"X-Crowdsec-Appsec-Verb\", method)\nreq.Header.Set(\"X-Crowdsec-Appsec-Host\", host)","handlingStrategy":"validation","validationCode":"if r.Header.Get(\"X-Crowdsec-Appsec-IP\") == \"\" {\n    // don't call NewParsedRequestFromRequest; reject or skip appsec\n}","typeGuard":null,"tryCatchPattern":"pr, _, _, err := NewParsedRequestFromRequest(r, logger)\nif err != nil {\n    log.Errorf(\"malformed appsec request: %v\", err)\n    http.Error(w, \"bad request\", http.StatusBadRequest)\n    return\n}","preventionTips":["Always route appsec traffic through a bouncer that sets the full header set","Add integration tests asserting X-Crowdsec-Appsec-* headers are present","Check proxies don't strip X- headers"],"tags":["appsec","headers","bouncer","validation"],"backgroundTag":"missing-required-header","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}