crowdsecurity/crowdsec · error
multiple headers with name %s found
Error message
multiple headers with name %s found
What it means
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.
Source
Thrown at pkg/appsec/api_validation/api_validation.go:267
switch input.SecurityScheme.In {
case "query":
//Because we are checking for the presence of the API key, it probably does not matter if go drops parameters using ; as a separator
values := input.RequestValidationInput.Request.URL.Query()[input.SecurityScheme.Name]
if len(values) == 0 {
return fmt.Errorf("query parameter %s not found", input.SecurityScheme.Name)
}
if len(values) > 1 {
return fmt.Errorf("multiple query parameters with name %s found", input.SecurityScheme.Name)
}
authTokenValue = values[0]
case "header":
canonicalHeaderName := http.CanonicalHeaderKey(input.SecurityScheme.Name)
values := input.RequestValidationInput.Request.Header[canonicalHeaderName]
if len(values) == 0 {
return fmt.Errorf("header %s not found", input.SecurityScheme.Name)
}
if len(values) > 1 {
return fmt.Errorf("multiple headers with name %s found", input.SecurityScheme.Name)
}
authTokenValue = values[0]
case "cookie":
cookieValues := input.RequestValidationInput.Request.CookiesNamed(input.SecurityScheme.Name)
if len(cookieValues) == 0 {
return fmt.Errorf("cookie %s not found", input.SecurityScheme.Name)
}
if len(cookieValues) > 1 {
return fmt.Errorf("multiple cookies with name %s found", input.SecurityScheme.Name)
}
authTokenValue = cookieValues[0].Value
default:
return fmt.Errorf("unsupported apiKey location %s", input.SecurityScheme.In)
}
case "oauth2", "openIdConnect":
if unsupportedPolicy == PolicyIgnore {
return nil
}View on GitHub (pinned to 909b515798)
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.
Example fix
// before
req.Header.Add("X-API-Key", k1)
req.Header.Add("X-API-Key", k2)
// after
req.Header.Set("X-API-Key", k1) Defensive patterns
Strategy: validation
Validate before calling
if len(req.Header.Values("X-API-Key")) != 1 { return errors.New("X-API-Key must be set exactly once") } Try / catch
err := validator.ValidateRequest(input); if err != nil { if strings.Contains(err.Error(), "multiple headers") { return ErrDuplicateHeader } return err } Prevention
- 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
When it happens
Trigger: 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.
Common situations: Duplicate headers from a proxy adding its own copy; client library appending instead of setting the header; smuggling/HPP test probes.
Understand the failure class
Background: "Invalid query parameter" / "Failed to parse value of ...": fixing bad query string parameters across APIs — this error's family across 36 libraries.
Related errors
- multiple query parameters with name %s found
- header %s not found
- multiple cookies with name %s found
- auth token is required but not provided
- query parameter %s not found
AI-assisted analysis of crowdsecurity/crowdsec@909b515798 (2026-09-06).
Data as JSON: /api/errors/0b7f5a32978be577.
Report an issue: GitHub.