spring-projects/spring-security · error · ServerExchangeRejectedException

The request was rejected because the parameter name

Error message

The request was rejected because the parameter name "<name>" is not allowed.

What it means

The firewall validates every request parameter name against the allowedParameterNames predicate. A parameter whose name fails is rejected with ServerExchangeRejectedException. This blocks parameter-pollution and malicious parameter-name injection (e.g. names with control characters).

Solutions

  1. Rename the parameter on the client to a valid name (alphanumerics, '-', '_', '.').
  2. If the parameter is legitimate, update the firewall: firewall.setAllowedParameterNames(name -> name.matches("[a-zA-Z0-9_.-]+")).
  3. Check logs to identify the exact rejected name and which client/endpoint sends it.
  4. Sanitize dynamically generated form/query parameter names at the source.

Example fix

// before: dynamic param name from user input
String url = "/api?" + userInput + "=1";
// after
String safeName = userInput.replaceAll("[^a-zA-Z0-9_.-]", "");
String url = "/api?" + safeName + "=1";
Defensive patterns

Strategy: validation

Validate before calling

boolean isSafeParameterName(String name) {
    return name != null && name.matches("[a-zA-Z0-9_.-]+") && !name.isEmpty();
}

Try / catch

try {
    exchange = firewall.getFirewalledExchange(exchange);
} catch (ServerExchangeRejectedException e) {
    log.warn("Rejected parameter name: {}", e.getMessage());
    return ResponseEntity.badRequest().build();
}

Prevention

When it happens

Trigger: A request (query string or form body) contains a parameter name that fails allowedParameterNames — e.g. names with special/control characters, or a custom predicate that doesn't include the parameter the client sends.

Common situations: APIs adding new query parameters after a restrictive setAllowedParameterNames predicate was configured; clients sending parameters with URL-encoded or malformed names; form fields auto-generated from user input; Spring Security upgrades changing default parameter validation.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/941357ec9225796e. Report an issue: GitHub.

Appendix: source

Thrown at web/src/main/java/org/springframework/security/web/server/firewall/StrictServerWebExchangeFirewall.java:649

	}

	private void validateAllowedHeaderName(String headerNames) {
		if (!StrictServerWebExchangeFirewall.this.allowedHeaderNames.test(headerNames)) {
			throw new ServerExchangeRejectedException(
					"The request was rejected because the header name \"" + headerNames + "\" is not allowed.");
		}
	}

	private void validateAllowedHeaderValue(Object key, @Nullable String value) {
		if (!StrictServerWebExchangeFirewall.this.allowedHeaderValues.test(value)) {
			throw new ServerExchangeRejectedException("The request was rejected because the header: \"" + key
					+ " \" has a value \"" + value + "\" that is not allowed.");
		}
	}

	private void validateAllowedParameterName(String name) {
		if (!StrictServerWebExchangeFirewall.this.allowedParameterNames.test(name)) {
			throw new ServerExchangeRejectedException(
					"The request was rejected because the parameter name \"" + name + "\" is not allowed.");
		}
	}

	private void validateAllowedParameterValue(String name, String value) {
		if (!StrictServerWebExchangeFirewall.this.allowedParameterValues.test(value)) {
			throw new ServerExchangeRejectedException("The request was rejected because the parameter: \"" + name
					+ " \" has a value \"" + value + "\" that is not allowed.");
		}
	}

	private static boolean encodedUrlContains(ServerHttpRequest request, String value) {
		if (valueContains(request.getPath().value(), value)) {
			return true;
		}
		return valueContains(request.getURI().getRawPath(), value);
	}

View on GitHub (pinned to 96852e8860)