apache/iceberg · error · UncheckedIOException
Failed to read StreamingOffset from json
Error message
Failed to read StreamingOffset from json
What it means
StreamingOffset.fromJson(InputStream) reads a JSON node from a stream before parsing it into a StreamingOffset. Any IOException while reading the stream is wrapped in UncheckedIOException with a generic 'Failed to read StreamingOffset from json' message and the original cause attached.
Source
Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/StreamingOffset.java:80
Preconditions.checkNotNull(json, "Cannot parse StreamingOffset JSON: null");
try {
JsonNode node = JsonUtil.mapper().readValue(json, JsonNode.class);
return fromJsonNode(node);
} catch (IOException e) {
throw new UncheckedIOException(
String.format("Failed to parse StreamingOffset from JSON string %s", json), e);
}
}
static StreamingOffset fromJson(InputStream inputStream) {
Preconditions.checkNotNull(inputStream, "Cannot parse StreamingOffset from inputStream: null");
JsonNode node;
try {
node = JsonUtil.mapper().readValue(inputStream, JsonNode.class);
} catch (IOException e) {
throw new UncheckedIOException("Failed to read StreamingOffset from json", e);
}
return fromJsonNode(node);
}
@Override
public String json() {
StringWriter writer = new StringWriter();
try (JsonGenerator generator = JsonUtil.factory().createGenerator(writer)) {
generator.writeStartObject();
generator.writeNumberField(VERSION, CURR_VERSION);
generator.writeNumberField(SNAPSHOT_ID, snapshotId);
generator.writeNumberField(POSITION, position);
generator.writeBooleanField(SCAN_ALL_FILES, scanAllFiles);
generator.writeEndObject();
generator.flush();
} catch (IOException e) {View on GitHub (pinned to 86d9c8fc54)
Solutions
- Check the wrapped cause for the underlying I/O failure (permissions, missing file, object-store error) and fix that.
- Retry the read — transient cloud-storage failures often resolve; ensure fresh stream per attempt.
- Verify the checkpoint offsets file still exists and isn't concurrently deleted by cleanup.
Example fix
// before
StreamingOffset offset = StreamingOffset.fromJson(cachedStream); // stream already consumed
// after
try (InputStream in = io.newInputFile(path).newStream()) {
StreamingOffset offset = StreamingOffset.fromJson(in);
} Defensive patterns
Strategy: retry
Validate before calling
if (!offsetFile.exists()) {
throw new IllegalStateException("Offset file missing: " + offsetFile);
} Try / catch
try (InputStream in = file.newStream()) {
return StreamingOffset.fromJson(in);
} catch (UncheckedIOException e) {
// inspect e.getCause(); retry transient object-store failures with backoff
} Prevention
- Open a fresh stream for each read attempt.
- Disable concurrent checkpoint cleanup while reading offsets.
- Use retry-with-backoff for cloud object-store reads.
When it happens
Trigger: The InputStream passed to fromJson is unreadable — closed stream, file deleted between listing and read, network/FileIO failure while streaming the checkpoint offset.
Common situations: Concurrent checkpoint cleanup deleting the offsets file mid-read; object-store transient errors (S3/GCS) when reading offset files; passing an already-consumed stream.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Failed to parse StreamingOffset from JSON string ${json}
- Failed to write StreamingOffset to json
- Failed writing offset to: %s
- Failed reading offset from: %s
- Failed to read StreamingOffset from json
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/04f5c5896a519402.
Report an issue: GitHub.