{"record":{"id":"9165d2b2ab89b1dd","repo":"apache/druid","slug":"unexpected-null-byte-s","errorCode":null,"errorMessage":"Unexpected null byte [%s]","messagePattern":"Unexpected null byte \\[(.+?)\\]","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/frame/field/ComplexFieldReader.java","lineNumber":124,"sourceCode":"      final ComplexMetricSerde serde,\n      final byte[] bytes,\n      final int position\n  )\n  {\n    final byte nullByte = bytes[position];\n\n    if (nullByte == ComplexFieldWriter.NULL_BYTE) {\n      return null;\n    } else if (nullByte == ComplexFieldWriter.NOT_NULL_BYTE) {\n      // Reads length in little-endian format\n      int length;\n      length = (bytes[position + 4] & 0xFF) << 24;\n      length |= (bytes[position + 3] & 0xFF) << 16;\n      length |= (bytes[position + 2] & 0xFF) << 8;\n      length |= (bytes[position + 1] & 0xFF);\n      return serde.fromBytes(bytes, position + ComplexFieldWriter.HEADER_SIZE, length);\n    } else {\n      throw new ISE(\"Unexpected null byte [%s]\", nullByte);\n    }\n  }\n\n  /**\n   * Alternative interface to read the field from the memory without creating a selector and field pointer\n   */\n  @Nullable\n  public static <T> T readFieldFromMemory(\n      final ComplexMetricSerde serde,\n      final Memory memory,\n      final long position\n  )\n  {\n    final byte nullByte = memory.getByte(position);\n\n    if (nullByte == ComplexFieldWriter.NULL_BYTE) {\n      return null;\n    } else if (nullByte == ComplexFieldWriter.NOT_NULL_BYTE) {","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/frame/field/ComplexFieldReader.java#L106-L142","documentation":"ComplexFieldReader.readFieldFromByteArray decodes a complex value from a byte array using a one-byte header (nullByte) that encodes null/inline/pointer layout. It throws ISE when the header byte is none of the recognized values, meaning the serialized bytes do not match the expected ComplexFieldWriter format.","triggerScenarios":"Reading a complex field from a byte array whose first header byte is not one of the documented NULL/inline/offset markers — typically corrupted data, a file written by a different writer version, or misaligned position into the byte array.","commonSituations":"Frames or segments written by an incompatible Druid version; manual byte manipulation that skips the header; memory corruption or truncated file being read at a wrong offset.","solutions":["Verify the bytes come from a ComplexFieldWriter-produced column and position points at the start of a field (the header byte).","Check that writer and reader Druid versions agree on the complex field layout.","Log/dump the offending nullByte value to identify which unexpected marker was found.","Rebuild or re-ingest the affected frame/segment if the data is corrupted."],"exampleFix":"// before\nbyte[] value = reader.readFieldFromByteArray(bytes, arbitraryOffset, serde);\n// after\nint offset = fieldPointer.position(); // must point at the ComplexFieldWriter header byte\nbyte[] value = reader.readFieldFromByteArray(bytes, offset, serde);","handlingStrategy":"validation","validationCode":"if (position < 0 || position >= bytes.length) { throw new IllegalArgumentException(\"position not at field start\"); }","typeGuard":null,"tryCatchPattern":"try { v = reader.readFieldFromByteArray(bytes, pos, serde); } catch (IllegalStateException e) { log.error(\"corrupt complex field, nullByte={}\", bytes[pos]); throw e; }","preventionTips":["Pass positions from field pointers, not manual arithmetic","Keep writer/reader Druid versions aligned","Checksum frame files before reading"],"tags":["serialization","complex-types","corruption"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}