{"record":{"id":"04f5c5896a519402","repo":"apache/iceberg","slug":"failed-to-read-streamingoffset-from-json","errorCode":null,"errorMessage":"Failed to read StreamingOffset from json","messagePattern":"Failed to read StreamingOffset from json","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"error","filePath":"spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/StreamingOffset.java","lineNumber":80,"sourceCode":"    Preconditions.checkNotNull(json, \"Cannot parse StreamingOffset JSON: null\");\n\n    try {\n      JsonNode node = JsonUtil.mapper().readValue(json, JsonNode.class);\n      return fromJsonNode(node);\n    } catch (IOException e) {\n      throw new UncheckedIOException(\n          String.format(\"Failed to parse StreamingOffset from JSON string %s\", json), e);\n    }\n  }\n\n  static StreamingOffset fromJson(InputStream inputStream) {\n    Preconditions.checkNotNull(inputStream, \"Cannot parse StreamingOffset from inputStream: null\");\n\n    JsonNode node;\n    try {\n      node = JsonUtil.mapper().readValue(inputStream, JsonNode.class);\n    } catch (IOException e) {\n      throw new UncheckedIOException(\"Failed to read StreamingOffset from json\", e);\n    }\n\n    return fromJsonNode(node);\n  }\n\n  @Override\n  public String json() {\n    StringWriter writer = new StringWriter();\n    try (JsonGenerator generator = JsonUtil.factory().createGenerator(writer)) {\n      generator.writeStartObject();\n      generator.writeNumberField(VERSION, CURR_VERSION);\n      generator.writeNumberField(SNAPSHOT_ID, snapshotId);\n      generator.writeNumberField(POSITION, position);\n      generator.writeBooleanField(SCAN_ALL_FILES, scanAllFiles);\n      generator.writeEndObject();\n      generator.flush();\n\n    } catch (IOException e) {","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/source/StreamingOffset.java#L62-L98","documentation":"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.","triggerScenarios":"The InputStream passed to fromJson is unreadable — closed stream, file deleted between listing and read, network/FileIO failure while streaming the checkpoint offset.","commonSituations":"Concurrent checkpoint cleanup deleting the offsets file mid-read; object-store transient errors (S3/GCS) when reading offset files; passing an already-consumed stream.","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."],"exampleFix":"// before\nStreamingOffset offset = StreamingOffset.fromJson(cachedStream); // stream already consumed\n\n// after\ntry (InputStream in = io.newInputFile(path).newStream()) {\n  StreamingOffset offset = StreamingOffset.fromJson(in);\n}","handlingStrategy":"retry","validationCode":"if (!offsetFile.exists()) {\n  throw new IllegalStateException(\"Offset file missing: \" + offsetFile);\n}","typeGuard":null,"tryCatchPattern":"try (InputStream in = file.newStream()) {\n  return StreamingOffset.fromJson(in);\n} catch (UncheckedIOException e) {\n  // inspect e.getCause(); retry transient object-store failures with backoff\n}","preventionTips":["Open a fresh stream for each read attempt.","Disable concurrent checkpoint cleanup while reading offsets.","Use retry-with-backoff for cloud object-store reads."],"tags":["spark","structured-streaming","io","json"],"backgroundTag":"file-read-failed","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}