apache/beam · error · NoSuchElementException
Current record is unavailable because either the reader is…
Error message
Current record is unavailable because either the reader is at the beginning of the input and start() or advance() wasn't called, or the last start() or advance() returned false.
What it means
SyntheticUnboundedSource's UnboundedReader.getCurrent() throws NoSuchElementException when no current record exists — i.e., start()/advance() has not yet been called successfully or the reader was not positioned. The synthetic unbounded source generates records continuously for streaming tests, and getCurrent() must only be read while positioned at an element.
Solutions
- Call start() once after createReader(), then check its boolean before reading getCurrent().
- Only call getCurrent() after a successful start() or when advance() returned true.
- Treat a false start()/advance() as end-of-data (for unbounded sources, an unusual condition) and stop reading.
Example fix
// before
UnboundedSource.UnboundedReader<KV<byte[], byte[]>> r = source.createReader(o, null);
KV<byte[], byte[]> kv = r.getCurrent();
// after
UnboundedSource.UnboundedReader<KV<byte[], byte[]>> r = source.createReader(o, null);
if (r.start()) {
KV<byte[], byte[]> kv = r.getCurrent();
} Defensive patterns
Strategy: type-guard
Type guard
boolean positioned(UnboundedSource.UnboundedReader<?> r) { try { r.getCurrent(); return true; } catch (NoSuchElementException e) { return false; } } Try / catch
try {
KV<byte[], byte[]> kv = reader.getCurrent();
} catch (NoSuchElementException e) {
// not started or exhausted — ensure start()/advance() contract is honored
} Prevention
- Call start() once after createReader() before any getCurrent().
- Check advance()'s return value each iteration.
- Never cache/defer getCurrent() results across start()/advance() boundaries.
When it happens
Trigger: Calling getCurrent() on a freshly created UnboundedReader before start(); or after advance() returned false / start() returned false. Also occurs in custom runner code reading the synthetic source out of protocol order.
Common situations: Streaming test harnesses (e.g., perf tests, TestStream-like setups) driving UnboundedReaders manually; runner bugs where watermark advancement is attempted before the reader is started on an empty or just-created reader.
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
- Current timestamp is unavailable because either the reader…
- The current element is unavailable because either the…
- GroupByKey cannot be applied to non-bounded PCollection in…
- Runner does not support draining.
- Support for unbounded plugins is not implemented!
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/eb44eae5a0d50e25.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/io/synthetic/src/main/java/org/apache/beam/sdk/io/synthetic/SyntheticUnboundedSource.java:157
public SyntheticUnboundedReader(SyntheticUnboundedSource source, long startOffset) {
this.currentKVPair = null;
this.delay = new ReaderDelay(sourceOptions);
this.source = source;
this.currentOffset = 0;
this.startOffset = startOffset;
this.syntheticWatermark = new SyntheticWatermark(sourceOptions, source.endOffset);
}
@Override
public SyntheticUnboundedSource getCurrentSource() {
return source;
}
@Override
public KV<byte[], byte[]> getCurrent() throws NoSuchElementException {
if (currentKVPair == null) {
throw new NoSuchElementException(
"Current record is unavailable because either the reader is "
+ "at the beginning of the input and start() or advance() wasn't called, "
+ "or the last start() or advance() returned false.");
}
return currentKVPair;
}
@Override
public Instant getCurrentTimestamp() throws NoSuchElementException {
if (eventTime == null) {
throw new NoSuchElementException(
"Current timestamp is unavailable because either the reader is "
+ "at the beginning of the input and start() or advance() wasn't called, "
+ "or the last start() or advance() returned false.");
}
return eventTime;
}
View on GitHub (pinned to 12126d8942)