{"record":{"id":"b94d46ea73a6ecf6","repo":"apache/druid","slug":"frame-of-size-d-not-yet-ready-to-read","errorCode":null,"errorMessage":"Frame of size [%,d] not yet ready to read","messagePattern":"Frame of size \\[%,d\\] not yet ready to read","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/frame/channel/ReadableByteChunksFrameChannel.java","lineNumber":356,"sourceCode":"    }\n  }\n\n  @VisibleForTesting\n  long getBytesBuffered()\n  {\n    synchronized (lock) {\n      return bytesBuffered;\n    }\n  }\n\n  private RowsAndColumns nextRAC()\n  {\n    final Memory compressedMemory;\n    final byte markerType;\n\n    synchronized (lock) {\n      if (!canReadFrame()) {\n        throw new ISE(\"Frame of size [%,d] not yet ready to read\", nextCompressedFrameLength);\n      }\n\n      if (nextCompressedFrameLength > Integer.MAX_VALUE - FRAME_MARKER_BYTES - FrameCompression.COMPRESSED_DATA_ENVELOPE_SIZE) {\n        throw new ISE(\"Cannot read frame of size [%,d] bytes\", nextCompressedFrameLength);\n      }\n\n      markerType = nextMarkerType;\n      final int numBytes = Ints.checkedCast(FRAME_MARKER_AND_COMPRESSED_ENVELOPE_BYTES + nextCompressedFrameLength);\n      compressedMemory = copyFromQueuedChunks(numBytes).region(\n          FRAME_MARKER_BYTES,\n          FRAME_MARKER_AND_COMPRESSED_ENVELOPE_BYTES + nextCompressedFrameLength - FRAME_MARKER_BYTES\n      );\n      deleteFromQueuedChunks(numBytes);\n      updateStreamState();\n    }\n\n    final byte[] decompressedBytes =\n        FrameCompression.decompress(compressedMemory, 0, compressedMemory.getCapacity());","sourceCodeStart":338,"sourceCodeEnd":374,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/frame/channel/ReadableByteChunksFrameChannel.java#L338-L374","documentation":"ReadableByteChunksFrameChannel buffers bytes from a producer and decodes complete frames into RowsAndColumns. When read() is invoked, it attempts to extract the next frame; if the buffered stream does not yet contain a full frame (canReadFrame() is false, meaning the announced length nextCompressedFrameLength has not fully arrived), it throws this ISE. It signals reading ahead of the writer.","triggerScenarios":"Calling read() before addChunk() has delivered all bytes of the current frame, i.e. bytesBuffered < FRAME_MARKER_AND_COMPRESSED_ENVELOPE_BYTES + nextCompressedFrameLength after a length was announced but not fully received.","commonSituations":"MSQ/stage-exchange consumers polling a channel whose producer task is still writing or has stalled; race between producer completion and consumer read; consumer error handling that ignores readyToRead() checks.","solutions":["Check readyToRead() (or canRead via the channel's state) before calling read().","Wait for the producer to finish writing: use a completion signal or await() on the channel instead of polling read().","Inspect the producer side for stalled/crashed tasks if the frame never arrives.","Enable debug logging on ReadableByteChunksFrameChannel to trace bytesAdded/bytesBuffered progress."],"exampleFix":"// before\nRowsAndColumns rac = channel.read();\n// after\nif (channel.readyToRead()) {\n  RowsAndColumns rac = channel.read();\n} else {\n  // wait for writer or idle() await\n}","handlingStrategy":"validation","validationCode":"if (!channel.readyToRead()) { /* await writer or idle */ } else { RowsAndColumns rac = channel.read(); }","typeGuard":"boolean isReady(ReadableByteChunksFrameChannel ch) { return ch.readyToRead(); }","tryCatchPattern":"try { rac = channel.read(); } catch (ISE e) { if (e.getMessage().contains(\"not yet ready\")) { /* defer read */ } else { throw e; } }","preventionTips":["Always gate read() on the channel's readiness/await API.","Treat the channel as producer-consumer: await writer completion or readiness before reading.","Log bytesAdded/bytesBuffered when debugging exchange stalls."],"tags":["druid","frame-channel","concurrency"],"backgroundTag":"invalid-state-transition","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}