{"record":{"id":"abcd00b076acd499","repo":"spring-projects/spring-security","slug":"encoding-failed","errorCode":null,"errorMessage":"Encoding failed","messagePattern":"Encoding failed","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"crypto/src/main/java/org/springframework/security/crypto/codec/Utf8.java","lineNumber":56,"sourceCode":"\n\tprivate Utf8() {\n\t}\n\n\t/**\n\t * Get the bytes of the String in UTF-8 encoded form.\n\t */\n\tpublic static byte[] encode(CharSequence string) {\n\t\tif (string == null) {\n\t\t\tthrow new IllegalArgumentException(\"String cannot be null\");\n\t\t}\n\t\ttry {\n\t\t\tByteBuffer bytes = CHARSET.newEncoder().encode(CharBuffer.wrap(string));\n\t\t\tbyte[] bytesCopy = new byte[bytes.limit()];\n\t\t\tSystem.arraycopy(bytes.array(), 0, bytesCopy, 0, bytes.limit());\n\t\t\treturn bytesCopy;\n\t\t}\n\t\tcatch (CharacterCodingException ex) {\n\t\t\tthrow new IllegalArgumentException(\"Encoding failed\", ex);\n\t\t}\n\t}\n\n\t/**\n\t * Decode the bytes in UTF-8 form into a String.\n\t */\n\tpublic static String decode(byte[] bytes) {\n\t\ttry {\n\t\t\treturn CHARSET.newDecoder().decode(ByteBuffer.wrap(bytes)).toString();\n\t\t}\n\t\tcatch (CharacterCodingException ex) {\n\t\t\tthrow new IllegalArgumentException(\"Decoding failed\", ex);\n\t\t}\n\t}\n\n\t/**\n\t * Constant time comparison to prevent against timing attacks.\n\t * @param expected the expected {@link CharSequence}","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/crypto/src/main/java/org/springframework/security/crypto/codec/Utf8.java#L38-L74","documentation":"Utf8.encode wraps the charset encoder, which throws CharacterCodingException when the CharSequence contains sequences of unpaired surrogates or otherwise malformed character data that cannot be encoded in UTF-8. The library rethrows it as an IllegalArgumentException with cause \"Encoding failed\".","triggerScenarios":"Calling Utf8.encode on a String containing isolated/unpaired surrogates (e.g. built from invalid char data read from a binary stream or a corrupted substring operation splitting a surrogate pair).","commonSituations":"Binary data read into Strings via wrong charset then re-encoded; string slicing that cut a surrogate pair in half; data deserialized from a broken serialization path.","solutions":["Fix the data source so the String contains valid Unicode (no unpaired surrogates).","Replace malformed chars before encoding: cs.toString().replaceAll(\"[\\\\uD800-\\\\uDFFF]\", \"\") when lossy cleanup is acceptable.","If the input is really binary, use byte[] end-to-end instead of routing through String."],"exampleFix":"// before\nbyte[] out = Utf8.encode(corruptedString); // unpaired surrogate\n// after\nString clean = corruptedString.codePoints().filter(cp -> Character.isValidCodePoint(cp) && !Character.isSurrogate((char) cp) || cp >= 0x10000 || cp < 0xD800 || cp > 0xDFFF).collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append).toString();\nbyte[] out = Utf8.encode(clean);","handlingStrategy":"try-catch","validationCode":"boolean encodable(CharSequence cs) { for (int i = 0; i < cs.length(); i++) { char c = cs.charAt(i); if (Character.isHighSurrogate(c) && (i + 1 >= cs.length() || !Character.isLowSurrogate(cs.charAt(i + 1)))) return false; } return true; }","typeGuard":null,"tryCatchPattern":"try { bytes = Utf8.encode(s); } catch (IllegalArgumentException e) { /* malformed unicode: sanitize or reject */ }","preventionTips":["Never build Strings from binary data using arbitrary charsets.","Avoid slicing strings at arbitrary indices that may split surrogate pairs.","Keep binary payloads as byte[] rather than round-tripping through String."],"tags":["utf8","encoding-failed","spring-security","character-encoding"],"backgroundTag":"invalid-argument-format","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"}