spring-projects/spring-security · error · Saml2Exception

Unable to inflate string

Error message

Unable to inflate string

What it means

Saml2Utils.samlInflate decompresses a raw-DEFLATE payload from a SAML redirect-binding request back into XML. This Saml2Exception wraps the IOException thrown by InflaterOutputStream when the input bytes are not valid deflate data or stream operations fail.

Source

Thrown at saml2/saml2-service-provider/src/main/java/org/springframework/security/saml2/provider/service/metadata/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

  1. Verify the IdP compresses with raw DEFLATE (zlib wrapper must not be present) before base64/URL-encoding
  2. Check the bytes are correctly base64-decoded and URL-decoded exactly once before inflation
  3. Test inflation manually: new Inflater(true) on the payload in a scratch program to confirm data integrity
  4. Inspect intermediary proxies/gateways for query-parameter rewriting
  5. If you control the sender, compare its compression output with Spring Security's own samlDeflate

Example fix

// before: feeding URL-encoded value directly
byte[] b = Base64.getDecoder().decode(requestParam);
// after: URL-decode first, then decode and inflate
byte[] b = Base64.getDecoder().decode(URLDecoder.decode(requestParam, StandardCharsets.UTF_8));
Defensive patterns

Strategy: validation

Validate before calling

boolean isProbablyDeflated(byte[] b) {
    if (b == null || b.length == 0) return false;
    try (var in = new InflaterInputStream(new ByteArrayInputStream(b), new Inflater(true))) {
        in.read(new byte[16]);
        return true;
    } catch (IOException ex) { return false; }
}

Try / catch

try {
    String xml = Saml2Utils.samlInflate(bytes);
} catch (Saml2Exception ex) {
    logger.warn("Invalid deflate payload from sender {}", senderEntityId, ex.getCause());
    // fall back to treating payload as uncompressed XML if your protocol allows
}

Prevention

When it happens

Trigger: Calling samlInflate with byte[] that is not valid raw-DEFLATE data (wrong compression, corrupted, or URL-decoded incorrectly) while processing an HTTP-Redirect binding SAML message.

Common situations: An IdP sends an incorrectly compressed SAMLRequest/SAMLResponse via redirect binding; a gateway/proxy mangles or re-encodes the query parameter; tests feed plain XML or gzip (with header) instead of raw deflate; custom serialization of the SAML message.

Related errors


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