{"id":"368bcc71cac39b75","repo":"apache/kafka","slug":"headers-cannot-be-null-368bcc","errorCode":null,"errorMessage":"Headers cannot be null","messagePattern":"Headers cannot be null","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/record/internal/DefaultRecord.java","lineNumber":200,"sourceCode":"\n        if (key == null) {\n            ByteUtils.writeVarint(-1, out);\n        } else {\n            int keySize = key.remaining();\n            ByteUtils.writeVarint(keySize, out);\n            Utils.writeTo(out, key, keySize);\n        }\n\n        if (value == null) {\n            ByteUtils.writeVarint(-1, out);\n        } else {\n            int valueSize = value.remaining();\n            ByteUtils.writeVarint(valueSize, out);\n            Utils.writeTo(out, value, valueSize);\n        }\n\n        if (headers == null)\n            throw new IllegalArgumentException(\"Headers cannot be null\");\n\n        ByteUtils.writeVarint(headers.length, out);\n\n        for (Header header : headers) {\n            String headerKey = header.key();\n            if (headerKey == null)\n                throw new IllegalArgumentException(\"Invalid null header key found in headers\");\n\n            byte[] utf8Bytes = Utils.utf8(headerKey);\n            ByteUtils.writeVarint(utf8Bytes.length, out);\n            out.write(utf8Bytes);\n\n            byte[] headerValue = header.value();\n            if (headerValue == null) {\n                ByteUtils.writeVarint(-1, out);\n            } else {\n                ByteUtils.writeVarint(headerValue.length, out);\n                out.write(headerValue);","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/record/internal/DefaultRecord.java#L182-L218","documentation":"DefaultRecord.writeTo (line 200), and the matching sizeOfBodyInBytes/sizeOf helpers, reject a null Header[] because the v2 record format always serialises a header-count varint. The contract is 'no headers' = Record.EMPTY_HEADERS, never null; passing null indicates the caller failed to normalise.","triggerScenarios":"Constructing records via low-level paths (DefaultRecord.writeTo / sizeInBytes) with a null headers argument; custom serializers, interceptors, or converters that propagate null instead of an empty array.","commonSituations":"Libraries that wrap records and forget to default headers; bridging from a format that omits headers; tests hand-building records.","solutions":["Pass Record.EMPTY_HEADERS (or new Header[0]) when there are no headers.","Initialise header fields eagerly at construction; never leave them null.","Normalise at the boundary: coerce null to an empty array before record assembly."],"exampleFix":"// before\nDefaultRecord.writeTo(out, delta, tsDelta, key, value, null);\n// after\nDefaultRecord.writeTo(out, delta, tsDelta, key, value, Record.EMPTY_HEADERS);","handlingStrategy":"validation","validationCode":"// Never pass null headers; substitute the empty array before producing/serializing\nimport org.apache.kafka.common.header.Header;\nimport org.apache.kafka.common.record.Record;\n\nHeader[] safeHeaders = (headers == null) ? Record.EMPTY_HEADERS : headers;\n// now safe to pass to DefaultRecord.writeTo(...) or ProducerRecord","typeGuard":"import org.apache.kafka.common.header.Header;\nimport org.apache.kafka.common.record.Record;\n\nstatic Header[] nonNullHeaders(Header[] headers) {\n    return headers == null ? Record.EMPTY_HEADERS : headers;\n}\n\n// usage: DefaultRecord.writeTo(out, offsetDelta, tsDelta, key, value, nonNullHeaders(headers));","tryCatchPattern":"try {\n    DefaultRecord.writeTo(out, offsetDelta, tsDelta, key, value, headers);\n} catch (IllegalArgumentException e) {\n    // headers was null; replace with Record.EMPTY_HEADERS and retry\n}","preventionTips":["The record format requires a non-null headers array; null is a programmer error, not a valid 'no headers' signal.","Use Record.EMPTY_HEADERS (or new Header[0]) to express 'no headers'.","Normalize at the boundary: coerce null headers to EMPTY_HEADERS as soon as user input enters your producer path.","Centralize record construction in one builder/factory so the null->empty normalization happens in exactly one place."],"tags":["record-format","serialization","headers"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}