{"record":{"id":"a6f9878254bbe063","repo":"apache/iceberg","slug":"malformed-input-partial-character-at-end-a6f987","errorCode":null,"errorMessage":"malformed input: partial character at end","messagePattern":"malformed input: partial character at end","errorType":"exception","errorClass":"UTFDataFormatException","httpStatus":null,"severity":"error","filePath":"flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/util/SerializerHelper.java","lineNumber":134,"sourceCode":"      switch (ch >> 4) {\n        case 0:\n        case 1:\n        case 2:\n        case 3:\n        case 4:\n        case 5:\n        case 6:\n        case 7:\n          /* 0xxxxxxx */\n          count++;\n          chararr[chararrCount++] = (char) ch;\n          break;\n        case 12:\n        case 13:\n          /* 110x xxxx 10xx xxxx */\n          count += 2;\n          if (count > utflen) {\n            throw new UTFDataFormatException(\"malformed input: partial character at end\");\n          }\n          char2 = bytearr[count - 1];\n          if ((char2 & 0xC0) != 0x80) {\n            throw new UTFDataFormatException(\"malformed input around byte \" + count);\n          }\n          chararr[chararrCount++] = (char) (((ch & 0x1F) << 6) | (char2 & 0x3F));\n          break;\n        case 14:\n          /* 1110 xxxx 10xx xxxx 10xx xxxx */\n          count += 3;\n          if (count > utflen) {\n            throw new UTFDataFormatException(\"malformed input: partial character at end\");\n          }\n          char2 = bytearr[count - 2];\n          char3 = bytearr[count - 1];\n          if (((char2 & 0xC0) != 0x80) || ((char3 & 0xC0) != 0x80)) {\n            throw new UTFDataFormatException(\"malformed input around byte \" + (count - 1));\n          }","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/util/SerializerHelper.java#L116-L152","documentation":"SerializerHelper.readLongUTF decodes modified UTF-8 byte-by-byte. A lead byte of 110xxxxx (cases 12-13) announces a 2-byte sequence; if the stream ends before the continuation byte arrives (count > utflen), the input is truncated and cannot be decoded. The method throws UTFDataFormatException because the encoded data is corrupt or cut off.","triggerScenarios":"Reading a stream whose byte length header (utflen) ends mid-character — i.e. a multi-byte UTF-8 sequence split across the declared end of data.","commonSituations":"Corrupted Flink checkpoint/state files; truncated network or file streams; bytes written by a producer using a different UTF-8 variant or wrong length header.","solutions":["Regenerate/re-read the data from a trusted source — the stream bytes are corrupt","Verify the writer and reader use the same SerializerHelper/DataOutput encoding","Check for truncation upstream (partial writes, short reads, wrong length prefix)","Validate byte payload integrity (checksums) before deserializing"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  String s = SerializerHelper.readLongUTF(in);\n} catch (UTFDataFormatException e) {\n  // treat stream as corrupt: fail the job or restore from a valid checkpoint\n  throw new IOException(\"corrupt UTF stream, restore from checkpoint\", e);\n}","preventionTips":["Verify no truncation between writer and reader (checksums, length validation)","Use matching serializer versions on produce/consume sides","Enable checkpoint integrity verification in Flink"],"tags":["flink","serialization","utf","corruption"],"backgroundTag":"checksum-mismatch","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}