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

  1. Confirm the message encoding matches the binding: GET/Redirect implies deflate(true); POST implies inflate(false) — check shouldConvertGetRequests and the request method
  2. Base64-decode the SAMLResponse yourself and try raw Inflater(true) on the bytes to see the exact zlib failure (unknown compression method, corrupt data)
  3. Check for truncation: query strings over URL length limits get cut off by proxies/browsers; inspect the raw parameter value length
  4. If the message exceeds 1 MiB decompressed, this is treated as a decompression attack; verify the IdP is not sending oversized messages
  5. 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

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


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