spring-projects/spring-security · error · ServerExchangeRejectedException
The request was rejected because the HTTP method
Error message
The request was rejected because the HTTP method "<method>" was not included within the list of allowed HTTP methods <allowedHttpMethods>
What it means
StrictServerWebExchangeFirewall restricts requests to a configured set of allowed HTTP methods. rejectForbiddenHttpMethod throws ServerExchangeRejectedException when the request method is not in allowedHttpMethods (unless configured to allow any method). This is an opt-in hardening: by default all methods are permitted, so this only fires after explicit configuration.
Solutions
- Add the missing method to the allowlist: firewall.setAllowedHttpMethods(new HashSet<>(List.of(GET, POST, PUT, DELETE, OPTIONS))).
- Add OPTIONS specifically to fix CORS preflight failures.
- If no restriction is desired, call setAllowedHttpMethods(ALLOW_ANY_HTTP_METHOD) to restore default behavior.
- Check client/probe method usage (health checks, preflight) and align the allowlist with what is genuinely used.
Example fix
// before
StrictServerWebExchangeFirewall firewall = new StrictServerWebExchangeFirewall();
firewall.setAllowedHttpMethods(Set.of(HttpMethod.GET, HttpMethod.POST));
// after
firewall.setAllowedHttpMethods(new HashSet<>(Arrays.asList(
HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, HttpMethod.DELETE, HttpMethod.OPTIONS))); Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight check against the configured allowlist
Set<HttpMethod> allowed = firewall.getAllowedHttpMethods();
if (allowed != ALLOW_ANY_HTTP_METHOD && !allowed.contains(HttpMethod.valueOf(method))) {
throw new IllegalArgumentException("Method not allowed by firewall: " + method);
} Try / catch
@ExceptionHandler(ServerExchangeRejectedException.class)
ResponseEntity<Void> handle(ServerExchangeRejectedException e) {
log.warn("Rejected method: {}", e.getMessage());
return ResponseEntity.status(HttpStatus.METHOD_NOT_ALLOWED).build();
} Prevention
- Always include OPTIONS in the allowlist for CORS preflight
- Include HEAD for health-check probes
- Keep the allowlist in config reviewed alongside API changes
- Use ALLOW_ANY_HTTP_METHOD unless restriction is required
When it happens
Trigger: The firewall bean was configured with setAllowedHttpMethods(Set<HttpMethod>) that omits a method the client uses (e.g. OPTIONS for CORS preflight, PATCH, or HEAD), so any request with that method is rejected during getFirewalledExchange.
Common situations: Hardening configuration forgetting OPTIONS, breaking CORS preflight; health-check probes using HEAD while only GET is allowed; API evolution adding PATCH/DELETE after the allowlist was fixed; load balancers issuing OPTIONS pings.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- The was rejected because it can only contain printable…
- The request was rejected because the URL contained a…
- The request was rejected because the URL was not normalized
- The requestURI cannot contain encoded slash. Got " +…
- The was rejected because it can only contain printable…
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/4373c00153449f72.
Report an issue: GitHub.
Appendix: source
Thrown at web/src/main/java/org/springframework/security/web/server/firewall/StrictServerWebExchangeFirewall.java:577
private void urlBlocklistsRemoveAll(Collection<String> values) {
this.encodedUrlBlocklist.removeAll(values);
this.decodedUrlBlocklist.removeAll(values);
}
private void rejectNonPrintableAsciiCharactersInFieldName(String toCheck, String propertyName) {
if (!containsOnlyPrintableAsciiCharacters(toCheck)) {
throw new ServerExchangeRejectedException(String
.format("The %s was rejected because it can only contain printable ASCII characters.", propertyName));
}
}
private void rejectForbiddenHttpMethod(ServerHttpRequest request) {
if (this.allowedHttpMethods == ALLOW_ANY_HTTP_METHOD) {
return;
}
if (!this.allowedHttpMethods.contains(request.getMethod())) {
throw new ServerExchangeRejectedException(
"The request was rejected because the HTTP method \"" + request.getMethod()
+ "\" was not included within the list of allowed HTTP methods " + this.allowedHttpMethods);
}
}
private void rejectedBlocklistedUrls(ServerHttpRequest request) {
for (String forbidden : this.encodedUrlBlocklist) {
if (encodedUrlContains(request, forbidden)) {
throw new ServerExchangeRejectedException(
"The request was rejected because the URL contained a potentially malicious String \""
+ forbidden + "\"");
}
}
for (String forbidden : this.decodedUrlBlocklist) {
if (decodedUrlContains(request, forbidden)) {
throw new ServerExchangeRejectedException(
"The request was rejected because the URL contained a potentially malicious String \""
+ forbidden + "\"");View on GitHub (pinned to 96852e8860)