apache/pulsar · error · IOException

Error seeking, new position

Error message

Error seeking, new position %d < current position %d

What it means

BlobStoreBackedInputStreamImpl is a forward-only stream over offloaded ledger data; seekForward(position) must never move the cursor backwards. If a caller requests a position earlier than the current cursor, it throws an IOException since the buffer cannot rewind what has already been consumed.

Solutions

  1. Ensure callers only request monotonically increasing positions when reading offloaded ledgers; re-open a fresh ReadHandle if backward access is needed
  2. Fix entry-position computation so reads are issued in ascending order (verify offload thresholds and entry offsets)
  3. If a rewind is genuinely required, recreate the input stream/ReadHandle instead of seeking backward

Example fix

// before: rewind attempt
readHandle.seekForward(oldPosition); // throws
// after: reopen for backward reads
if (oldPosition < stream.getCurrentPosition()) {
  stream = reopenReadHandle(ledgerId);
}
stream.seekForward(oldPosition);
Defensive patterns

Strategy: validation

Validate before calling

// guard before seeking
long cur = stream.getCurrentPosition();
if (position < cur) {
  throw new IllegalArgumentException("cannot seek backward: " + position + " < " + cur);
}

Try / catch

try {
  stream.seekForward(position);
} catch (IOException e) {
  if (e.getMessage().contains("new position") && e.getMessage().contains("< current position")) {
    stream = reopenReadHandle(ledgerId); // rewind requires a fresh stream
  } else throw e;
}

Prevention

When it happens

Trigger: BookKeeper read-handle seek logic calls seekForward with a position smaller than the stream's current position — typically when ledger entry reads are issued out of order or a caller re-reads an entry already passed.

Common situations: Reading entries of an offloaded ledger non-monotonically (e.g. after a consumer/reader rewind or a wrong entry-id computation); caller caching stale entry positions and re-reading; bug in ReadHandle interpolation of offload positions.

Related errors


AI-assisted analysis of apache/pulsar@820761864e (2026-09-06). Data as JSON: /api/errors/ca58568644c68cac. Report an issue: GitHub.

Appendix: source

Thrown at tiered-storage/jcloud/src/main/java/org/apache/bookkeeper/mledger/offload/jcloud/impl/BlobStoreBackedInputStreamImpl.java:188

        log.debug().attr("position", position).attr("bucket", bucket).attr("key", key)
                .attr("cursor", cursor).attr("bufStart", bufferOffsetStart)
                .attr("bufEnd", bufferOffsetEnd).log("Seeking");
        if (position >= bufferOffsetStart && position <= bufferOffsetEnd) {
            long newIndex = position - bufferOffsetStart;
            buffer.readerIndex((int) newIndex);
        } else {
            bufferOffsetStart = bufferOffsetEnd = -1;
            this.cursor = position;
            buffer.clear();
        }
    }

    @Override
    public void seekForward(long position) throws IOException {
        if (position >= cursor) {
            seek(position);
        } else {
            throw new IOException(String.format("Error seeking, new position %d < current position %d",
                                                position, cursor));
        }
    }

    public long getCurrentPosition() {
        if (bufferOffsetStart != -1) {
            return bufferOffsetStart + buffer.readerIndex();
        }
        return cursor + buffer.readerIndex();
    }

    @Override
    public void close() {
        buffer.release();
    }

    @Override
    public int available() throws IOException {

View on GitHub (pinned to 820761864e)