apache/iceberg · error · UncheckedIOException
Failed to parse StreamingOffset from JSON string %s
Error message
Failed to parse StreamingOffset from JSON string %s
What it means
StreamingOffset.fromJson throws UncheckedIOException wrapping the message when the offset's JSON string cannot be parsed into a JsonNode (malformed JSON, I/O error from Jackson). It converts the checked IOException into an unchecked one so it can surface from Spark checkpoint deserialization.
Source
Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/source/StreamingOffset.java:68
* @param snapshotId The current processed snapshot id.
* @param position The position of last scanned file in snapshot.
* @param scanAllFiles whether to scan all files in a snapshot; for example, to read all data when
* starting a stream.
*/
StreamingOffset(long snapshotId, long position, boolean scanAllFiles) {
this.snapshotId = snapshotId;
this.position = position;
this.scanAllFiles = scanAllFiles;
}
static StreamingOffset fromJson(String json) {
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);
}
@OverrideView on GitHub (pinned to 86d9c8fc54)
Solutions
- Inspect and repair the checkpoint location's offset/state JSON files
- Delete the corrupted checkpoint and restart the streaming query (data will be reprocessed per source semantics)
- Verify all executors/drivers use the same Iceberg version
- If calling fromJson manually, validate the string is well-formed JSON before passing it
Example fix
// before
StreamingOffset offset = StreamingOffset.fromJson(userProvidedString); // may throw
// after
try {
StreamingOffset offset = StreamingOffset.fromJson(json);
} catch (UncheckedIOException e) {
// fall back to re-initializing offsets from the table
} Defensive patterns
Strategy: try-catch
Validate before calling
try { JsonUtil.mapper().readTree(offsetJson); } catch (Exception e) { /* reject/re-initialize before passing to fromJson */ } Try / catch
try {
StreamingOffset offset = StreamingOffset.fromJson(json);
} catch (UncheckedIOException e) {
// treat as corrupt checkpoint: re-initialize offsets from table state
} Prevention
- Never hand-edit Spark checkpoint files
- Keep the same Iceberg version on all nodes of a streaming job
- Monitor checkpoint directory for truncation/corruption; re-create checkpoints after version upgrades
When it happens
Trigger: Spark structured streaming restores a StreamingOffset from checkpoint state where the stored JSON string is corrupt, truncated, or produced by an incompatible schema/version; calling fromJson directly with a non-JSON string.
Common situations: Corrupted or hand-edited checkpoint files; offset JSON written by a different Iceberg version that fails to parse; disk issues truncating checkpoint files during recovery after failure.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to read StreamingOffset from json
- Failed to parse StreamingOffset from JSON string ${json}
- Cannot load current offset at snapshot %d, the snapshot was
- Failed to parse StreamingOffset from JSON string %s
- Failed to read StreamingOffset from json
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/8a55dee3a0f3e826.
Report an issue: GitHub.