{"record":{"id":"459b215bb8538c61","repo":"apache/iceberg","slug":"unrecognized-header-bytes-0x-02x-0x-02x","errorCode":null,"errorMessage":"Unrecognized header bytes: 0x%02X 0x%02X","messagePattern":"Unrecognized header bytes: 0x%02X 0x%02X","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/avro/AvroEncoderUtil.java","lineNumber":75,"sourceCode":"      // Encode the datum with avro schema.\n      BinaryEncoder encoder = EncoderFactory.get().binaryEncoder(out, null);\n      DatumWriter<T> writer = new GenericAvroWriter<>(avroSchema);\n      writer.write(datum, encoder);\n      encoder.flush();\n\n      return out.toByteArray();\n    }\n  }\n\n  public static <T> T decode(byte[] data) throws IOException {\n    try (ByteArrayInputStream in = new ByteArrayInputStream(data, 0, data.length)) {\n      DataInputStream dataInput = new DataInputStream(in);\n\n      // Read the magic bytes\n      byte header0 = dataInput.readByte();\n      byte header1 = dataInput.readByte();\n      if (header0 != MAGIC_BYTES[0] || header1 != MAGIC_BYTES[1]) {\n        throw new IllegalStateException(\n            String.format(\n                Locale.ROOT, \"Unrecognized header bytes: 0x%02X 0x%02X\", header0, header1));\n      }\n\n      // Read avro schema\n      Schema avroSchema = new Schema.Parser().parse(dataInput.readUTF());\n\n      // Decode the datum with the parsed avro schema.\n      BinaryDecoder binaryDecoder = DecoderFactory.get().binaryDecoder(in, null);\n      DatumReader<T> reader = new GenericAvroReader<>(avroSchema);\n      reader.setSchema(avroSchema);\n      return reader.read(null, binaryDecoder);\n    }\n  }\n}\n","sourceCodeStart":57,"sourceCodeEnd":91,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/avro/AvroEncoderUtil.java#L57-L91","documentation":"AvroEncoderUtil.decode expects the input stream to begin with the Iceberg Avro magic bytes header. When the first two bytes read do not match MAGIC_BYTES, it fails fast with the actual byte values found. This indicates the buffer is not an Iceberg-encoded Avro value, or was produced/corrupted by a different format or version.","triggerScenarios":"Calling AvroEncoderUtil.decode with a byte[]/InputStream whose first two bytes are not the expected magic bytes — e.g. passing a plain Avro blob, a Parquet/ORC payload, a truncated or corrupted buffer, or data encoded by a different tool version.","commonSituations":"Passing raw Avro-serialized data instead of Iceberg's AvroEncoderUtil.encode output; version mismatch where an older/newer writer changed the envelope format; byte-offset mistakes that skip or misalign the header; data corruption in transit or storage.","solutions":["Verify the byte[] was produced by AvroEncoderUtil.encode and is being passed unmodified to decode","Check the first bytes of the payload against the expected magic bytes before decoding","Check for truncation or an offset error so decoding starts at the true beginning of the buffer","Regenerate the payload with the same Iceberg version used to read it"],"exampleFix":"// before\nbyte[] payload = rawAvroBytes; // not produced by AvroEncoderUtil.encode\nT value = AvroEncoderUtil.decode(payload);\n\n// after\nbyte[] payload = AvroEncoderUtil.encode(datum, schema, icebergSchema);\nT value = AvroEncoderUtil.decode(payload);","handlingStrategy":"validation","validationCode":"byte[] expected = AvroEncoderUtil.MAGIC_BYTES; // or known header\nif (payload.length < 2 || payload[0] != expected[0] || payload[1] != expected[1]) {\n  throw new IllegalArgumentException(\"payload is not an Iceberg Avro-encoded blob\");\n}","typeGuard":"boolean isIcebergAvroPayload(byte[] b) { return b != null && b.length >= 2; } // check against magic constants","tryCatchPattern":"try { return AvroEncoderUtil.decode(payload); } catch (IllegalStateException e) { if (e.getMessage().startsWith(\"Unrecognized header bytes\")) { /* regenerate or re-route payload */ } throw e; }","preventionTips":["Only pass byte[] produced by AvroEncoderUtil.encode to decode","Keep the same Iceberg version on writer and reader paths","Beware byte[] slicing offsets when storing payloads in queues/blobs"],"tags":["avro","magic-bytes","decode","corruption"],"backgroundTag":"invalid-argument-format","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}