spring-projects/spring-security · error · IllegalArgumentException
Failed to decode SAMLResponse
Error message
Failed to decode SAMLResponse
What it means
Base64Checker.checkAcceptable validates that a SAMLResponse parameter is an acceptable Base64 string before decoding: every character must be ignored-or-in-alphabet, the length mod 4 must not be 1, and the unused bits of an incomplete final chunk must be zero. When validation fails it throws IllegalArgumentException('Failed to decode SAMLResponse'). This guards the requireBase64(true) path used when reading the SAMLResponse request parameter.
Source
Thrown at saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/registration/Saml2Utils.java:189
}
}
// in cases of an incomplete final chunk, ensure the unused bits are zero
switch (goodChars % 4) {
case 0:
return true;
case 2:
return (lastGoodCharVal & 0b1111) == 0;
case 3:
return (lastGoodCharVal & 0b11) == 0;
default:
return false;
}
}
void checkAcceptable(String ins) {
if (!isAcceptable(ins)) {
throw new IllegalArgumentException("Failed to decode SAMLResponse");
}
}
}
}
static class CappedOutputStream extends OutputStream {
private static final long MAX_SIZE = 1024 * 1024;
private final OutputStream delegate;
private int size;
CappedOutputStream(OutputStream delegate) {
this.delegate = delegate;
}View on GitHub (pinned to 96852e8860)
Solutions
- Log the failing samlResponse value (safe, it failed validation) and inspect for HTML entities (&#..;), '+' replaced by ' ', or truncation
- URL-decode the parameter before Base64 checking if handling the raw query string yourself; the framework normally does this in request.getParameter
- Compare the value length and charset with what the IdP actually sent (capture at the IdP or via network trace)
- Treat it as an authentication failure: the Base64 check is a security control; do not bypass it — reject the response
- If the IdP legitimately sends non-canonical Base64, verify with getSaml2AuthenticationTokenConverter configuration that requireBase64 applies to your binding
Example fix
// before: raw value contains HTML entities
String encoded = request.getParameter("SAMLResponse"); // "PHNhbWxw...
"
// after: ensure parameter passed through the servlet's URL decoding, or strip whitespace/entity noise
String encoded = request.getParameter("SAMLResponse").replaceAll("\\s", "");
if (encoded == null || encoded.isEmpty()) {
throw new Saml2AuthenticationException(Saml2Error.invalidResponse("missing SAMLResponse"), null);
} Defensive patterns
Strategy: validation
Validate before calling
private static final java.util.regex.Pattern B64 = java.util.regex.Pattern.compile("^[A-Za-z0-9+/\\r\\n]+={0,2}$");
boolean acceptableBase64(String s) {
return s != null && !s.isEmpty() && s.length() % 4 != 1 && B64.matcher(s).matches();
}
if (!acceptableBase64(request.getParameter("SAMLResponse"))) { reject(); } Type guard
boolean isUsableSamlResponse(String s) { return s != null && s.length() > 8 && s.length() % 4 != 1; } Try / catch
try { decoding.decode(); } catch (IllegalArgumentException ex) { throw new Saml2AuthenticationException(Saml2Error.invalidResponse("SAMLResponse is not valid Base64"), ex); } Prevention
- URL-decode request parameters before Base64 validation when handling raw query strings
- Reject empty or whitespace-only SAMLResponse parameters early with a clear error
- Check for intermediaries (proxies, WAFs) rewriting or truncating the parameter
- Never bypass the Base64 check — it is a security control against malformed input
When it happens
Trigger: Passing a string that fails the Base64 structural check to Saml2Utils.withEncoded(...).requireBase64(true).decode(): e.g. length % 4 == 1, non-Base64 characters that decode ambiguously, non-zero padding bits in a trailing 2- or 3-character chunk, or a null/empty parameter being validated.
Common situations: IdP or intermediary HTML-escapes or corrupts the SAMLResponse parameter; a load balancer or framework truncates/re-encodes the form value; a client sends tampered or garbage samlResponse values (often malicious probing); custom code feeds a URL-encoded (still %-xx) string in without decoding it first.
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to decode SAMLResponse
- Failed to decode SAMLResponse
- Failed to decode SAMLResponse
- Metadata response is missing the necessary IDPSSODescriptor
- Unable to inflate string
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/a58a92b97aec1444.
Report an issue: GitHub.