{"record":{"id":"d450c3dfd769d436","repo":"oracle/graal","slug":"malformed-input-partial-character-at-end","errorCode":null,"errorMessage":"malformed input: partial character at end","messagePattern":"malformed input: partial character at end","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/BinaryInput.java","lineNumber":301,"sourceCode":"                    break;\n                case 12:\n                case 13:\n                    /* 110x xxxx 10xx xxxx */\n                    byteCount += 2;\n                    if (byteCount > len) {\n                        throw new IllegalArgumentException(\"Partial character at end\");\n                    }\n                    c2 = tempEncodingByteBuffer[byteCount - 1];\n                    if ((c2 & 0xC0) != 0x80) {\n                        throw new IllegalArgumentException(\"malformed input around byte \" + byteCount);\n                    }\n                    tempEncodingCharBuffer[charCount++] = (char) (((c1 & 0x1F) << 6) | (c2 & 0x3F));\n                    break;\n                case 14:\n                    /* 1110 xxxx 10xx xxxx 10xx xxxx */\n                    byteCount += 3;\n                    if (byteCount > len) {\n                        throw new IllegalArgumentException(\"malformed input: partial character at end\");\n                    }\n                    c2 = tempEncodingByteBuffer[byteCount - 2];\n                    c3 = tempEncodingByteBuffer[byteCount - 1];\n                    if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80)) {\n                        throw new IllegalArgumentException(\"malformed input around byte \" + (byteCount - 1));\n                    }\n                    tempEncodingCharBuffer[charCount++] = (char) (((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));\n                    break;\n                default:\n                    /* 10xx xxxx, 1111 xxxx */\n                    throw new IllegalArgumentException(\"malformed input around byte \" + byteCount);\n            }\n        }\n        // The number of chars produced may be less than len\n        return new String(tempEncodingCharBuffer, 0, charCount);\n    }\n\n    /**","sourceCodeStart":283,"sourceCodeEnd":319,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/truffle/BinaryInput.java#L283-L319","documentation":"When a 3-byte UTF-8 sequence (lead byte 1110xxxx) begins too close to the end of the buffer, byteCount+3 exceeds len and BinaryInput throws IllegalArgumentException('malformed input: partial character at end'). The string payload is truncated in the middle of a multi-byte character.","triggerScenarios":"readUTF on a buffer whose remaining length is 1-2 bytes short of the full 3-byte sequence, i.e. the declared length disagrees with the encoded content.","commonSituations":"Truncated transfer between the host JVM and libgraal; a length field computed with the wrong character-vs-byte semantics on the producer side; buffer reuse where an old shorter string overwrote a longer one.","solutions":["On the producer, compute the encoded byte length with the same utfLen loop BinaryOutput.writeUTF uses (1/2/3 bytes per char), not String.length().","Verify the total byte count transferred matches the header written for the string.","Use matching GraalVM versions on both peers so the length encoding (short vs LARGE_STRING_TAG header) agrees.","Discard and rebuild corrupted buffers instead of partial re-reads."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    String s = in.readUTF();\n} catch (IllegalArgumentException e) {\n    if (e.getMessage() != null && e.getMessage().contains(\"partial character at end\")) {\n        // truncated 3-byte sequence: re-request the record\n    }\n}","preventionTips":["Compute byte lengths with char-based 1/2/3 rule, never String.length()","Match header size (short vs LARGE_STRING_TAG) on both sides","Discard corrupted buffers instead of partial re-reads"],"tags":["libgraal","truffle","encoding","utf-8","marshalling"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}