apache/iceberg · warning · java.io.IOException
No mark defined
Error message
No mark defined
What it means
SingleBufferInputStream.reset() restores the stream to the position captured by mark(), but the mark is cleared after a single reset and mark is only set by an explicit call. IOException "No mark defined" is thrown when reset() is called without a preceding mark() call, or after the mark has already been consumed/reset once.
Solutions
- Call mark(position) before reset(); re-mark after each reset if you need to rewind again.
- Restructure the reader to track its own position and use seek() instead of mark/reset.
- Wrap reset() in a check of markSupported()/your own saved position rather than relying on repeated resets.
- If repeat rewinding is needed, duplicate the stream or re-create it from the source ByteBuffer.
Example fix
// before stream.reset(); stream.reset(); // second reset: No mark defined // after stream.mark(0); stream.reset(); stream.mark(0); // re-mark before resetting again stream.reset();
Defensive patterns
Strategy: try-catch
Try / catch
try {
stream.reset();
} catch (IOException e) {
if ("No mark defined".equals(e.getMessage())) {
stream.seek(savedPosition); // rewind via explicit position instead
} else {
throw e;
}
} Prevention
- Always call mark(position) immediately before any planned reset()
- Remember mark is one-shot: re-mark after each reset if rewinding repeatedly
- Prefer seek(pos) over mark/reset for repeatable rewinds on this stream
When it happens
Trigger: Calling reset() before calling mark(pos), or calling reset() twice without re-marking, or after the underlying read consumed the marked state.
Common situations: Code ported from streams assumed mark() was implicit; retries that call reset() twice to rewind; copy/paste of stream logic where the first reset succeeded and a second one fails.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/462508129f8b528e.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/io/SingleBufferInputStream.java:189
ByteBuffer remaining = buffer.duplicate();
buffer.position(buffer.limit());
return Collections.singletonList(remaining);
}
@Override
public void mark(int readlimit) {
this.mark = buffer.position();
}
@Override
public void reset() throws IOException {
if (mark >= 0) {
buffer.position(mark);
this.mark = -1;
} else {
throw new IOException("No mark defined");
}
}
@Override
public boolean markSupported() {
return true;
}
@Override
public int available() {
return buffer.remaining();
}
}
View on GitHub (pinned to 86d9c8fc54)