{"record":{"id":"3a1362fcb6d4325d","repo":"apache/druid","slug":"value-overrun","errorCode":null,"errorMessage":"Value overrun","messagePattern":"Value overrun","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/frame/field/StringFieldReader.java","lineNumber":579,"sourceCode":"            isEffectivelyNull = true;\n          }\n\n          // Skip; next byte will be a null/not-null byte or a row terminator.\n          break;\n\n        case StringFieldWriter.ROW_TERMINATOR:\n          // Skip; this is the end of the row, so we'll fall through to the return statement.\n          rowTerminatorSeen = true;\n          break;\n\n        case StringFieldWriter.NULL_BYTE:\n          list.add(null);\n          break;\n\n        case StringFieldWriter.NOT_NULL_BYTE:\n          for (long i = position; ; i++) {\n            if (i >= limit) {\n              throw new ISE(\"Value overrun\");\n            }\n\n            final byte b = memory.getByte(i);\n\n            if (b == StringFieldWriter.VALUE_TERMINATOR) {\n              final int len = Ints.checkedCast(i - position);\n\n              final ByteBuffer buf = FrameReaderUtils.readByteBuffer(memory, position, len);\n              list.add(buf);\n\n              position += len;\n\n              break;\n            }\n          }\n\n          break;\n","sourceCodeStart":561,"sourceCodeEnd":597,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/frame/field/StringFieldReader.java#L561-L597","documentation":"addStringsToList decodes a string (or string array) field from the frame's memory, walking bytes until a VALUE_TERMINATOR. If a non-null value starts but the field's limit is reached before the terminator, the physical encoding is truncated or corrupted beyond the expected region, so \"Value overrun\" is thrown. This indicates frame corruption or reading past the field's declared bounds.","triggerScenarios":"Reading a frame whose string field bytes are truncated (e.g. frame buffer cut short, wrong limit passed to readStringsFromMemory), so a NOT_NULL_BYTE is seen but no VALUE_TERMINATOR exists before limit.","commonSituations":"Frames written by a bugged or mismatched Druid version being read by a different version (serialization change); corrupted on-disk/durable-storage frame files; incorrect offset arithmetic in custom code reading raw frame memory.","solutions":["Verify the frame file/bytes are complete and uncorrupted (re-run the query or re-fetch the frame).","Ensure the writer and reader Druid versions match for frame serialization.","Check that the position/limit passed to the reader come from the frame's own field boundaries, not manual arithmetic."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  reader.readStringsFromMemory(memory, position, limit, list);\n} catch (IllegalStateException e) {\n  if (e.getMessage().contains(\"Value overrun\")) {\n    throw new CorruptFrameException(\"Frame data truncated; regenerate frame\", e);\n  }\n  throw e;\n}","preventionTips":["Use frame-provided field offsets/limits instead of manual arithmetic.","Keep writer and reader on the same Druid version for frame format compatibility.","Validate frame checksums/lengths when frames come from durable storage."],"tags":["frame-corruption","string-field","decoder","druid"],"backgroundTag":"internal-invariant-violation","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"}