apache/druid · error · IllegalStateException

Invalid midstream marker

Error message

Invalid midstream marker (id = %s, position = %d)

What it means

In the FRAMES stream part, every byte read at a marker position must be a valid frame marker (a data frame marker or MARKER_NO_MORE_FRAMES). Any other byte indicates the stream is not aligned to frame boundaries, so the reader throws with the channel id and byte position. This catches desynchronization or corruption mid-stream.

Solutions

  1. Regenerate the stream/file and retry the stage.
  2. Confirm only one writer owns the channel and files aren't shared across tasks.
  3. Check disk/filesystem integrity for the spool directory.
  4. Compare Druid versions of writer and reader.
Defensive patterns

Strategy: try-catch

Try / catch

try { rac = channel.read(); } catch (ISE e) { if (e.getMessage().startsWith("Invalid midstream marker")) { failStage("frame stream misaligned", e); } else { throw e; } }

Prevention

When it happens

Trigger: updateStreamState reads a marker byte in StreamPart.FRAMES that is neither a frame marker nor FrameFileWriter.MARKER_NO_MORE_FRAMES.

Common situations: Corrupted spool files on disk; two writers appending to the same stream; wrong file passed to ReadableByteChunksFrameChannel; byte offset drift due to earlier skipped/failed read.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/a03e9f4f46214fab. Report an issue: GitHub.

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/frame/channel/ReadableByteChunksFrameChannel.java:435

          // Read nextFrameLength if needed; otherwise do nothing.
          // Both MARKER_FRAME and MARKER_RAC use the same compression envelope format.
          final int bytesRequiredToReadLength = FRAME_MARKER_BYTES + FrameCompression.COMPRESSED_DATA_HEADER_SIZE;

          if (nextCompressedFrameLength == UNKNOWN_LENGTH && bytesBuffered >= bytesRequiredToReadLength) {
            nextMarkerType = markerByte;
            nextCompressedFrameLength = copyFromQueuedChunks(bytesRequiredToReadLength)
                .getLong(FRAME_MARKER_BYTES + Byte.BYTES /* Compression strategy byte */);

            if (nextCompressedFrameLength <= 0 || nextCompressedFrameLength >= MAX_FRAME_SIZE_BYTES) {
              throw new ISE("Invalid frame size (size = %,d B)", nextCompressedFrameLength);
            }
          }
        } else if (markerByte == FrameFileWriter.MARKER_NO_MORE_FRAMES) {
          streamPart = StreamPart.FOOTER;
          nextCompressedFrameLength = UNKNOWN_LENGTH;
          nextMarkerType = NO_MARKER;
        } else {
          throw new ISE("Invalid midstream marker (id = %s, position = %d)", id, bytesAdded - bytesBuffered);
        }
      }
    }

    if (streamPart == StreamPart.FOOTER) {
      if (bytesBuffered > 0) {
        // Footer is discarded: it isn't useful when reading frame files as streams. (It contains pointers
        // for random access of frames.)
        deleteFromQueuedChunks(bytesBuffered);
      }

      assert bytesBuffered == 0 && chunks.isEmpty() && nextCompressedFrameLength == UNKNOWN_LENGTH;
    }

    if (addChunkBackpressureFuture != null && (bytesBuffered < bytesLimit || !canReadFrame())) {
      // Release backpressure.
      addChunkBackpressureFuture.set(null);
      addChunkBackpressureFuture = null;

View on GitHub (pinned to 9b90983fd2)