{"record":{"id":"be1ef28aa91dfa25","repo":"apache/iceberg","slug":"failed-to-decode-partition","errorCode":null,"errorMessage":"Failed to decode partition","messagePattern":"Failed to decode partition","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"error","filePath":"flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/maintenance/operator/StructLikeSerializer.java","lineNumber":121,"sourceCode":"        boolean isNull = dis.readBoolean();\n        if (isNull) {\n          partition.set(i, null);\n        } else {\n          int length = dis.readInt();\n          byte[] bytes = new byte[length];\n          dis.readFully(bytes);\n          Object value = Conversions.fromByteBuffer(fields.get(i).type(), ByteBuffer.wrap(bytes));\n          // Conversions returns CharBuffer for STRING; PartitionData (and the manifest writer)\n          // expects String.\n          if (value instanceof CharSequence cs && !(value instanceof String)) {\n            value = cs.toString();\n          }\n\n          partition.set(i, value);\n        }\n      }\n    } catch (IOException e) {\n      throw new UncheckedIOException(\"Failed to decode partition\", e);\n    }\n\n    return partition;\n  }\n\n  private void writeField(StructLike struct, int pos, Type fieldType) throws IOException {\n    Object value = struct.get(pos, Object.class);\n    if (value == null) {\n      dos.writeBoolean(true);\n      return;\n    }\n\n    dos.writeBoolean(false);\n    ByteBuffer buf = Conversions.toByteBuffer(fieldType, value);\n    dos.writeInt(buf.remaining());\n    dos.write(buf.array(), buf.arrayOffset() + buf.position(), buf.remaining());\n  }\n}","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/maintenance/operator/StructLikeSerializer.java#L103-L139","documentation":"StructLikeSerializer.decodePartition reads back bytes produced by encodePartition into a new StructLike; an IOException while reading is wrapped in an UncheckedIOException. This usually means the byte array is truncated, corrupt, or was not produced by encodePartition with the same partition type.","triggerScenarios":"Calling decodePartition with bytes that are malformed, truncated, or encoded against a different/older partition type (field count or type mismatch while reading fields).","commonSituations":"State restored across schema evolution (partition spec changed), corrupted keyed state in checkpoints, or manually constructed byte arrays.","solutions":["Ensure the partitionType passed to decodePartition matches the one used to encode the bytes.","Check for schema/partition spec evolution between when state was written and read back.","If state is corrupt, restore from an earlier checkpoint or rebuild state."],"exampleFix":"// before\nStructLike p = StructLikeSerializer.decodePartition(bytes, currentSpec.partitionType());\n// after\n// use the spec captured when the bytes were encoded\nStructLike p = StructLikeSerializer.decodePartition(bytes, specAtEncodeTime.partitionType());","handlingStrategy":"validation","validationCode":"// Verify bytes length and partition type match what was used at encode time before decoding","typeGuard":null,"tryCatchPattern":"try { StructLike p = StructLikeSerializer.decodePartition(bytes, spec.partitionType()); } catch (UncheckedIOException e) { LOG.error(\"Partition decode failed; spec mismatch or corrupt bytes\", e); }","preventionTips":["Always decode with the same partition type used to encode","Beware partition spec evolution invalidating persisted encoded partitions","Restore from healthy checkpoints if state corruption is suspected"],"tags":["flink","deserialization","partitioning"],"backgroundTag":"json-parse-error","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"}