spring-projects/spring-security · error · IllegalArgumentException
Failed to decode SAMLResponse
Error message
Failed to decode SAMLResponse
What it means
Thrown by Saml2Utils.checkAcceptable after a base64-decoded SAMLResponse fails the acceptability check: the decoded bytes must begin with '<' (an XML document) and contain only acceptable characters. This means the base64 decode succeeded but the result is not a plausible SAML XML payload, usually because the value was corrupted, double-encoded, or not actually a SAMLResponse. It is a defensive check against malformed or malicious input before inflation/parsing.
Source
Thrown at saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/web/authentication/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
- Verify the sender uses HTTP-POST binding: base64 of raw XML, not deflated-then-encoded XML
- Log the first decoded byte and confirm it is '<' before delegating; re-encode on the test side if not
- Check for intermediaries (proxies, WAFs) altering the SAMLResponse parameter (line wrapping, '+' becoming ' ')
- Ensure the form field is posted with proper URL encoding (application/x-www-form-urlencoded) and not truncated
Example fix
// before (wrong: deflating then encoding for POST binding) byte[] deflated = deflate(samlResponseXml); String samlResponse = Base64.getEncoder().encodeToString(deflated); // after (POST binding: plain base64 of XML) String samlResponse = Base64.getEncoder().encodeToString(samlResponseXml.getBytes(StandardCharsets.UTF_8));
Defensive patterns
Strategy: validation
Validate before calling
byte[] decoded = Base64.getDecoder().decode(samlResponseParam);
if (decoded.length == 0 || decoded[0] != '<') {
throw new IllegalArgumentException("SAMLResponse is not base64-encoded XML");
} Try / catch
try { /* saml processing */ } catch (IllegalArgumentException ex) {
log.warn("Malformed SAMLResponse from remote party", ex);
response.sendError(HttpServletResponse.SC_BAD_REQUEST);
} Prevention
- Match binding (POST = plain base64, Redirect = deflate+base64) on both IDP and SP
- URL-encode the parameter end-to-end and test through proxies
- Sanity-check decoded payloads start with '<' before shipping integrations
When it happens
Trigger: Passing a SAMLResponse parameter whose base64-decoded bytes do not start with '<', a value that was base64-encoded twice, a truncated or whitespace/newline-corrupted POST body, or sending an artifact/encrypted blob where a plain SAMLResponse is expected.
Common situations: IDP and SP disagree on POST vs Redirect binding encoding; a proxy or load balancer re-encodes/re-chunks the SAMLResponse form field; the client sends a deflated-then-encoded value (Redirect binding style) via POST; copy-pasted test values with line breaks.
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
- Invalid len
- Invalid maxolen
- An error occurred while attempting to decode the Jwt: Malfor
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/28569bbd7ab7bbd3.
Report an issue: GitHub.