{"record":{"id":"0b7f5a32978be577","repo":"crowdsecurity/crowdsec","slug":"multiple-headers-with-name-s-found","errorCode":null,"errorMessage":"multiple headers with name %s found","messagePattern":"multiple headers with name (.+?) found","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/appsec/api_validation/api_validation.go","lineNumber":267,"sourceCode":"\t\t\tswitch input.SecurityScheme.In {\n\t\t\tcase \"query\":\n\t\t\t\t//Because we are checking for the presence of the API key, it probably does not matter if go drops parameters using ; as a separator\n\t\t\t\tvalues := input.RequestValidationInput.Request.URL.Query()[input.SecurityScheme.Name]\n\t\t\t\tif len(values) == 0 {\n\t\t\t\t\treturn fmt.Errorf(\"query parameter %s not found\", input.SecurityScheme.Name)\n\t\t\t\t}\n\t\t\t\tif len(values) > 1 {\n\t\t\t\t\treturn fmt.Errorf(\"multiple query parameters with name %s found\", input.SecurityScheme.Name)\n\t\t\t\t}\n\t\t\t\tauthTokenValue = values[0]\n\t\t\tcase \"header\":\n\t\t\t\tcanonicalHeaderName := http.CanonicalHeaderKey(input.SecurityScheme.Name)\n\t\t\t\tvalues := input.RequestValidationInput.Request.Header[canonicalHeaderName]\n\t\t\t\tif len(values) == 0 {\n\t\t\t\t\treturn fmt.Errorf(\"header %s not found\", input.SecurityScheme.Name)\n\t\t\t\t}\n\t\t\t\tif len(values) > 1 {\n\t\t\t\t\treturn fmt.Errorf(\"multiple headers with name %s found\", input.SecurityScheme.Name)\n\t\t\t\t}\n\t\t\t\tauthTokenValue = values[0]\n\t\t\tcase \"cookie\":\n\t\t\t\tcookieValues := input.RequestValidationInput.Request.CookiesNamed(input.SecurityScheme.Name)\n\t\t\t\tif len(cookieValues) == 0 {\n\t\t\t\t\treturn fmt.Errorf(\"cookie %s not found\", input.SecurityScheme.Name)\n\t\t\t\t}\n\t\t\t\tif len(cookieValues) > 1 {\n\t\t\t\t\treturn fmt.Errorf(\"multiple cookies with name %s found\", input.SecurityScheme.Name)\n\t\t\t\t}\n\t\t\t\tauthTokenValue = cookieValues[0].Value\n\t\t\tdefault:\n\t\t\t\treturn fmt.Errorf(\"unsupported apiKey location %s\", input.SecurityScheme.In)\n\t\t\t}\n\t\tcase \"oauth2\", \"openIdConnect\":\n\t\t\tif unsupportedPolicy == PolicyIgnore {\n\t\t\t\treturn nil\n\t\t\t}","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/appsec/api_validation/api_validation.go#L249-L285","documentation":"While resolving an apiKey security scheme located in a header, the named header appeared more than once in the incoming HTTP request. The validator refuses to guess which value is the token, so API-key extraction fails and the request is treated as failing the security requirement.","triggerScenarios":"A validated request contains two or more headers with the securityScheme's name (len(values) > 1) at pkg/appsec/api_validation/api_validation.go:267.","commonSituations":"Duplicate headers from a proxy adding its own copy; client library appending instead of setting the header; smuggling/HPP test probes.","solutions":["Send the auth header exactly once per request.","Use Header.Set instead of Header.Add in client code to avoid duplicates.","Audit proxy/middleware chains for headers being merged or re-added."],"exampleFix":"// before\nreq.Header.Add(\"X-API-Key\", k1)\nreq.Header.Add(\"X-API-Key\", k2)\n// after\nreq.Header.Set(\"X-API-Key\", k1)","handlingStrategy":"validation","validationCode":"if len(req.Header.Values(\"X-API-Key\")) != 1 { return errors.New(\"X-API-Key must be set exactly once\") }","typeGuard":null,"tryCatchPattern":"err := validator.ValidateRequest(input); if err != nil { if strings.Contains(err.Error(), \"multiple headers\") { return ErrDuplicateHeader } return err }","preventionTips":["Use Header.Set (replaces) instead of Header.Add (appends) for auth headers","Audit middleware that injects auth headers","Watch for Go http clients retrying and duplicating headers"],"tags":["appsec","openapi","api-key","header","duplicate"],"backgroundTag":"invalid-query-parameter","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}