{"record":{"id":"0e716456d328f925","repo":"spring-projects/spring-security","slug":"unable-to-inflate-string-0e7164","errorCode":null,"errorMessage":"Unable to inflate string","messagePattern":"Unable to inflate string","errorType":"exception","errorClass":"Saml2Exception","httpStatus":null,"severity":"error","filePath":"saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/authentication/logout/Saml2Utils.java","lineNumber":76,"sourceCode":"\t\t\tdeflater.write(s.getBytes(StandardCharsets.UTF_8));\n\t\t\tdeflater.finish();\n\t\t\treturn b.toByteArray();\n\t\t}\n\t\tcatch (IOException ex) {\n\t\t\tthrow new Saml2Exception(\"Unable to deflate string\", ex);\n\t\t}\n\t}\n\n\tstatic String samlInflate(byte[] b) {\n\t\ttry {\n\t\t\tByteArrayOutputStream out = new ByteArrayOutputStream();\n\t\t\tInflaterOutputStream iout = new InflaterOutputStream(out, new Inflater(true));\n\t\t\tiout.write(b);\n\t\t\tiout.finish();\n\t\t\treturn new String(out.toByteArray(), StandardCharsets.UTF_8);\n\t\t}\n\t\tcatch (IOException ex) {\n\t\t\tthrow new Saml2Exception(\"Unable to inflate string\", ex);\n\t\t}\n\t}\n\n\tstatic EncodingConfigurer withDecoded(String decoded) {\n\t\treturn new EncodingConfigurer(decoded);\n\t}\n\n\tstatic DecodingConfigurer withEncoded(String encoded) {\n\t\treturn new DecodingConfigurer(encoded);\n\t}\n\n\tstatic final class EncodingConfigurer {\n\n\t\tprivate final String decoded;\n\n\t\tprivate boolean deflate;\n\n\t\tprivate EncodingConfigurer(String decoded) {","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/authentication/logout/Saml2Utils.java#L58-L94","documentation":"Saml2Utils.samlInflate decompresses a raw (nowrap) DEFLATE byte stream used by SAML HTTP-Redirect binding; an IOException during inflation is wrapped in this Saml2Exception. It almost always means the input bytes are not a valid raw DEFLATE stream — a wrong decoding step was applied or the payload is corrupted.","triggerScenarios":"Calling Saml2Utils.samlInflate(byte[]) with bytes that are not raw-DEFLATE data: base64 decoding was skipped or wrong, the peer produced zlib-wrapped rather than raw deflate, or the bytes are plaintext XML passed in directly.","commonSituations":"Redirect-binding SAMLRequest/SAMLResponse handling where the caller inflated before base64-decoding; tampered or truncated query parameters; double-compressed payloads from a misconfigured IdP; using standard Base64 instead of URL-safe/Base64 without padding where required.","solutions":["Confirm the input is base64-decoded first (Saml2Utils.samlDecode) before inflating — inflate is never the first step.","Ensure raw DEFLATE (nowrap) is what the peer sent; a zlib header means the bytes are malformed for this method.","Log the first bytes of the input to verify it is binary compressed data, not base64 text or XML.","Catch the Saml2Exception and reject the request as invalid; do not retry unmodified input."],"exampleFix":"// before\nString xml = Saml2Utils.samlInflate(request.getParameter(\"SAMLRequest\").getBytes());\n// Saml2Exception: Unable to inflate string\n// after\nbyte[] decoded = Saml2Utils.samlDecode(request.getParameter(\"SAMLRequest\"));\nString xml = Saml2Utils.samlInflate(decoded);","handlingStrategy":"validation","validationCode":"byte[] decoded = Saml2Utils.samlDecode(param); // base64 first\nif (decoded == null || decoded.length == 0) {\n    throw new IllegalArgumentException(\"Empty SAML message after base64 decode\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    String xml = Saml2Utils.samlInflate(decoded);\n} catch (Saml2Exception ex) {\n    throw new AuthenticationServiceException(\"SAML message is not valid DEFLATE data\", ex);\n}","preventionTips":["Always base64-decode before inflating — inflate is never the first step.","Expect raw DEFLATE (nowrap), not zlib-wrapped data.","Log first input bytes when diagnosing to spot plaintext/base64 passed by mistake.","Reject (do not retry) requests whose inflate fails — likely tampering or misconfiguration."],"tags":["saml2","inflate","redirect-binding","compression"],"backgroundTag":"decompression-failed","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}