{"record":{"id":"9eda74a31cd7fcd4","repo":"apache/iceberg","slug":"failed-to-read-streamingoffset-from-json-9eda74","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/v4.1/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/v4.1/spark/src/main/java/org/apache/iceberg/spark/source/StreamingOffset.java#L62-L98","documentation":"StreamingOffset.fromJson(InputStream) throws UncheckedIOException with this message when reading the JSON node from the supplied InputStream fails with an IOException (stream read error, invalid encoding, etc.). The caller should close the stream after this method returns.","triggerScenarios":"Deserializing a StreamingOffset from an InputStream whose bytes are not valid JSON or that fails mid-read — e.g. a checkpoint file stream that is truncated or unreadable at recovery time.","commonSituations":"Corrupted checkpoint offset files; network/distributed filesystem transient failures while reading the offset stream; passing an already-consumed (empty) stream.","solutions":["Re-read from a fresh, valid InputStream containing JSON of form {\"version\":N,\"snapshot_id\":...,\"position\":...,\"scan_all_files\":...}","Repair or regenerate the checkpoint file, or restart the stream from a clean checkpoint","Check filesystem/network health for the underlying storage (HDFS/S3)"],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"if (inputStream == null || inputStream.available() == 0) { throw new IllegalStateException(\"empty offset stream\"); }","typeGuard":null,"tryCatchPattern":"try {\n  StreamingOffset offset = StreamingOffset.fromJson(stream);\n} catch (UncheckedIOException e) {\n  // fall back to reading offsets from the table / fresh checkpoint\n}","preventionTips":["Always pass a fresh stream positioned at file start","Verify checkpoint files are fully written (no partial uploads) on the object store","Handle transient storage failures with retry before treating offsets as corrupt"],"tags":["spark","streaming","json","io","deserialization"],"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"}