spring-projects/spring-security · error · Saml2Exception
Unable to inflate string
Error message
Unable to inflate string
What it means
Saml2Utils.samlInflate RAW-DEFLATE decompresses a Base64-decoded SAML message (typically a GET-bound SAMLResponse) and re-raises any IOException as a Saml2Exception. It throws when the input bytes are not a valid raw-DEFLATE stream, or when the decompressed output exceeds the 1 MiB CappedOutputStream limit. Since inflate is expected only for HTTP-Redirect (GET) responses, this usually means the payload was malformed or not actually deflated.
Source
Thrown at saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/registration/Saml2Utils.java:74
deflater.write(s.getBytes(StandardCharsets.UTF_8));
deflater.finish();
return b.toByteArray();
}
catch (IOException ex) {
throw new Saml2Exception("Unable to deflate string", ex);
}
}
static String samlInflate(byte[] b) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
InflaterOutputStream iout = new InflaterOutputStream(new CappedOutputStream(out), new Inflater(true));
iout.write(b);
iout.finish();
return new String(out.toByteArray(), StandardCharsets.UTF_8);
}
catch (IOException ex) {
throw new Saml2Exception("Unable to inflate string", ex);
}
}
static EncodingConfigurer withDecoded(String decoded) {
return new EncodingConfigurer(decoded);
}
static DecodingConfigurer withEncoded(String encoded) {
return new DecodingConfigurer(encoded);
}
static final class EncodingConfigurer {
private final String decoded;
private boolean deflate;
private EncodingConfigurer(String decoded) {View on GitHub (pinned to 96852e8860)
Solutions
- Confirm the message encoding matches the binding: GET/Redirect implies deflate(true); POST implies inflate(false) — check shouldConvertGetRequests and the request method
- Base64-decode the SAMLResponse yourself and try raw Inflater(true) on the bytes to see the exact zlib failure (unknown compression method, corrupt data)
- Check for truncation: query strings over URL length limits get cut off by proxies/browsers; inspect the raw parameter value length
- If the message exceeds 1 MiB decompressed, this is treated as a decompression attack; verify the IdP is not sending oversized messages
- Wrap the decode call and treat Saml2AuthenticationException invalid_response as an authentication failure, not a crash
Example fix
// before (converter misconfigured) converter.setShouldConvertGetRequests(false); // GET SAMLResponse now decoded without inflate handling mismatch // after converter.setShouldConvertGetRequests(true); // GET => inflate(true), POST => no inflate, matching the IdP binding
Defensive patterns
Strategy: try-catch
Validate before calling
// decode-only sanity check before handing to the library
byte[] raw = java.util.Base64.getMimeDecoder().decode(encoded);
java.util.zip.Inflater probe = new java.util.zip.Inflater(true);
probe.setInput(raw);
byte[] buf = new byte[64];
boolean ok = probe.inflate(buf) > 0 || probe.getRemaining() > 0;
probe.end();
if (!ok) { throw new IllegalArgumentException("payload is not raw-DEFLATE"); } Type guard
boolean looksInflatable(byte[] b) { return b != null && b.length > 2 && (b[0] & 0x0F) <= 7; } // first deflate byte hints block type Try / catch
try { decoded = decoding.decode(); } catch (Saml2Exception ex) { throw new Saml2AuthenticationException(Saml2Error.invalidResponse("not a valid deflated SAML message"), ex); } Prevention
- Match inflate(true) only to HTTP-Redirect/GET bindings; POST messages are not deflated
- Check shouldConvertGetRequests matches how your IdP sends responses
- Beware URL length limits (~8KB) that truncate deflated GET payloads
- Treat inflate failures as rejected authentication attempts, possibly attack traffic
When it happens
Trigger: Decoding an encoded SAMLResponse whose bytes are not valid raw-DEFLATE data (e.g. it was not compressed, was zlib-wrapped instead of raw-deflated, was truncated, or is garbage); or a decompressed payload larger than 1 MiB (which surfaces as the CappedOutputStream IOException wrapped here).
Common situations: IdP sends a POST-style (non-deflated) message but the request arrived via GET and inflate(true) was applied; a proxy/HTML form truncated the query-string payload; attacker-supplied tampered SAMLResponse; a decompression-bomb attempt hitting the 1 MiB cap.
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
- Unable to inflate string
- Unable to inflate string
- Unable to inflate string
- Unable to deflate string
- Unable to deflate string
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/eb712e10eecf6adc.
Report an issue: GitHub.