{"id":"5df898fbb399e9da","repo":"apache/kafka","slug":"invalid-magic-value-5df898","errorCode":null,"errorMessage":"Invalid magic value {}","messagePattern":"Invalid magic value (.+?)","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/record/internal/LegacyRecord.java","lineNumber":447,"sourceCode":"                             long crc,\n                             byte attributes,\n                             long timestamp,\n                             byte[] key,\n                             byte[] value) throws IOException {\n        write(out, magic, crc, attributes, timestamp, wrapNullable(key), wrapNullable(value));\n    }\n\n    // Write a record to the buffer, if the record's compression type is none, then\n    // its value payload should be already compressed with the specified type\n    private static void write(DataOutputStream out,\n                              byte magic,\n                              long crc,\n                              byte attributes,\n                              long timestamp,\n                              ByteBuffer key,\n                              ByteBuffer value) throws IOException {\n        if (magic != RecordBatch.MAGIC_VALUE_V0 && magic != RecordBatch.MAGIC_VALUE_V1)\n            throw new IllegalArgumentException(\"Invalid magic value \" + magic);\n        if (timestamp < 0 && timestamp != RecordBatch.NO_TIMESTAMP)\n            throw new IllegalArgumentException(\"Invalid message timestamp \" + timestamp);\n\n        // write crc\n        out.writeInt((int) (crc & 0xffffffffL));\n        // write magic value\n        out.writeByte(magic);\n        // write attributes\n        out.writeByte(attributes);\n\n        // maybe write timestamp\n        if (magic > RecordBatch.MAGIC_VALUE_V0)\n            out.writeLong(timestamp);\n\n        // write the key\n        if (key == null) {\n            out.writeInt(-1);\n        } else {","sourceCodeStart":429,"sourceCodeEnd":465,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/record/internal/LegacyRecord.java#L429-L465","documentation":"Thrown by LegacyRecord.write when the magic argument is neither MAGIC_VALUE_V0 (0) nor MAGIC_VALUE_V1 (1). LegacyRecord only supports message-format versions 0 and 1; magic 2+ belongs to the default RecordBatch implementation. This guard prevents silently writing a v2 payload through the v0/v1 wire format.","triggerScenarios":"Calling LegacyRecord.write / LegacyRecord.create with a magic byte other than 0 or 1. Reachable from producer code that constructs legacy records, from converter/upgrade tooling, or from any code path that picks LegacyRecord for a format it does not support.","commonSituations":"A custom serializer or test helper hard-coded magic=2 but still routes through LegacyRecord; mixing up RecordBatch magic constants with legacy constants; or message.format.version interop code that did not gate on the version before choosing the writer.","solutions":["At the call site, branch on the magic byte: use LegacyRecord only for magic 0/1, and DefaultRecordBatch / DefaultRecord for magic 2+.","If you are upgrading a producer to v2, switch the writer class entirely — LegacyRecord is not the v2 path.","Add a precondition in your factory method so magic is validated once, at the boundary, rather than deep inside write().","Double-check log.message.format.version / message.format.version broker config — if it is 2 or higher, no LegacyRecord code path should be producing records."],"exampleFix":"// before: LegacyRecord used for every magic, throws on v2\nLegacyRecord.create(magic, ts, key, value);\n\n// after: route by message-format version\nif (magic < RecordBatch.MAGIC_VALUE_V2) {\n    LegacyRecord.create(magic, ts, key, value);\n} else {\n    MemoryRecords.withRecords(magic, compression, new SimpleRecord(ts, key, value));\n}","handlingStrategy":"type-guard","validationCode":"if (magic != RecordBatch.MAGIC_VALUE_V0 && magic != RecordBatch.MAGIC_VALUE_V1) {\n    throw new IllegalArgumentException(\n        \"LegacyRecord magic must be 0 or 1, got \" + magic);\n}\nLegacyRecord.create(magic, timestamp, key, value);","typeGuard":"static boolean isLegacyMagic(byte magic) {\n    return magic == RecordBatch.MAGIC_VALUE_V0\n        || magic == RecordBatch.MAGIC_VALUE_V1;\n}\n\n// usage:\nif (!isLegacyMagic(magic)) {\n    throw new IllegalArgumentException(\"Not a legacy magic: \" + magic);\n}","tryCatchPattern":null,"preventionTips":["Reference RecordBatch.MAGIC_VALUE_V0 / MAGIC_VALUE_V1 constants, never raw literals like 0 or 1.","Default to the modern v2 format (MAGIC_VALUE_V2) unless you specifically need legacy wire compat.","Centralize magic selection in one config-driven factory so an invalid value fails fast at startup."],"tags":["legacy-record","magic","message-format","version","validation"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}