{"record":{"id":"0f33e83583c1ed3f","repo":"spring-projects/spring-security","slug":"the-request-was-rejected-because-the-header-key","errorCode":null,"errorMessage":"The request was rejected because the header: \"<key> \" has a value \"<value>\" that is not allowed.","messagePattern":"The request was rejected because the header: \"<key> \" has a value \"<value>\" that is not allowed\\.","errorType":"exception","errorClass":"ServerExchangeRejectedException","httpStatus":400,"severity":"error","filePath":"web/src/main/java/org/springframework/security/web/server/firewall/StrictServerWebExchangeFirewall.java","lineNumber":642,"sourceCode":"\t\tif (!isNormalized(request.getURI().getRawPath())) {\n\t\t\treturn false;\n\t\t}\n\t\tif (!isNormalized(request.getURI().getPath())) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate void validateAllowedHeaderName(String headerNames) {\n\t\tif (!StrictServerWebExchangeFirewall.this.allowedHeaderNames.test(headerNames)) {\n\t\t\tthrow new ServerExchangeRejectedException(\n\t\t\t\t\t\"The request was rejected because the header name \\\"\" + headerNames + \"\\\" is not allowed.\");\n\t\t}\n\t}\n\n\tprivate void validateAllowedHeaderValue(Object key, @Nullable String value) {\n\t\tif (!StrictServerWebExchangeFirewall.this.allowedHeaderValues.test(value)) {\n\t\t\tthrow new ServerExchangeRejectedException(\"The request was rejected because the header: \\\"\" + key\n\t\t\t\t\t+ \" \\\" has a value \\\"\" + value + \"\\\" that is not allowed.\");\n\t\t}\n\t}\n\n\tprivate void validateAllowedParameterName(String name) {\n\t\tif (!StrictServerWebExchangeFirewall.this.allowedParameterNames.test(name)) {\n\t\t\tthrow new ServerExchangeRejectedException(\n\t\t\t\t\t\"The request was rejected because the parameter name \\\"\" + name + \"\\\" is not allowed.\");\n\t\t}\n\t}\n\n\tprivate void validateAllowedParameterValue(String name, String value) {\n\t\tif (!StrictServerWebExchangeFirewall.this.allowedParameterValues.test(value)) {\n\t\t\tthrow new ServerExchangeRejectedException(\"The request was rejected because the parameter: \\\"\" + name\n\t\t\t\t\t+ \" \\\" has a value \\\"\" + value + \"\\\" that is not allowed.\");\n\t\t}\n\t}\n","sourceCodeStart":624,"sourceCodeEnd":660,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/web/src/main/java/org/springframework/security/web/server/firewall/StrictServerWebExchangeFirewall.java#L624-L660","documentation":"The firewall validates each header's value against the allowedHeaderValues predicate. A value that fails the test causes a ServerExchangeRejectedException naming the header key and offending value. This blocks CRLF injection and other header-value smuggling attacks.","triggerScenarios":"A request header (key) has a value failing allowedHeaderValues — typically values containing CR/LF, non-printable characters, non-ASCII text, or control characters inserted by clients or intermediaries.","commonSituations":"Users pasting multi-line content into a header value (e.g. custom tracing or locale headers); clients setting values with unencoded Unicode; proxies appending suspicious values; overly strict custom allowedHeaderValues predicates rejecting legitimate values after a config change.","solutions":["Sanitize the header value on the client: strip CR/LF and control/non-ASCII characters before sending.","Review the rejected value in logs and relax the setAllowedHeaderValues predicate if the value is legitimate (e.g. allow printable ASCII).","Fix intermediary proxies/servers that append or rewrite the header with illegal characters.","If it's an attack probe, block the source; the firewall is working as intended."],"exampleFix":"// before: client sets raw user input in header\nrequest.headers.set(\"X-Note\", userInput); // may contain \\n or control chars\n// after\nrequest.headers.set(\"X-Note\",\n    userInput.replaceAll(\"[\\\\r\\\\n\\\\x00-\\\\x1F]\", \"\"));","handlingStrategy":"validation","validationCode":"boolean isSafeHeaderValue(String value) {\n    return value != null && value.matches(\"[\\\\x20-\\\\x7E]+\") && !value.contains(\"\\r\") && !value.contains(\"\\n\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    exchange = firewall.getFirewalledExchange(exchange);\n} catch (ServerExchangeRejectedException e) {\n    log.warn(\"Rejected header value: {}\", e.getMessage());\n    return ResponseEntity.badRequest().build();\n}","preventionTips":["Strip CR/LF and control characters from header values before setting them.","Restrict header values to printable ASCII or properly encode them.","Never put unvalidated user input into header values.","Test custom allowedHeaderValues predicates with edge-case values (newline, unicode, empty)."],"tags":["security","spring-security","http-headers","crlf-injection"],"backgroundTag":"invalid-argument-value","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}