{"record":{"id":"90ace5eb90505985","repo":"apache/iceberg","slug":"failed-reading-offset-from-s","errorCode":null,"errorMessage":"Failed reading offset from: %s","messagePattern":"Failed reading offset from: (.+?)","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"critical","filePath":"spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/SparkMicroBatchStream.java","lineNumber":310,"sourceCode":"    }\n\n    private void writeOffset(StreamingOffset offset, OutputFile file) {\n      try (OutputStream outputStream = file.create()) {\n        BufferedWriter writer =\n            new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));\n        writer.write(offset.json());\n        writer.flush();\n      } catch (IOException ioException) {\n        throw new UncheckedIOException(\n            String.format(\"Failed writing offset to: %s\", initialOffsetLocation), ioException);\n      }\n    }\n\n    private StreamingOffset readOffset(InputFile file) {\n      try (InputStream in = file.newStream()) {\n        return StreamingOffset.fromJson(in);\n      } catch (IOException ioException) {\n        throw new UncheckedIOException(\n            String.format(\"Failed reading offset from: %s\", initialOffsetLocation), ioException);\n      }\n    }\n  }\n}\n","sourceCodeStart":292,"sourceCodeEnd":316,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/source/SparkMicroBatchStream.java#L292-L316","documentation":"readOffset deserializes the persisted StreamingOffset JSON via StreamingOffset.fromJson from the initial offset location file. Any IOException while opening or reading the stream is wrapped in this UncheckedIOException. It means the previously written offset could not be read back, typically because the file is missing, unreadable, or the storage backend failed mid-read.","triggerScenarios":"initialOffset()/batch flow calls readOffset(file) and file.newStream() throws — offset file deleted from the checkpoint location, permissions revoked, or S3/HDFS read failure (throttling, connection reset).","commonSituations":"Checkpoint directory cleaned up by retention jobs while the query is live; S3 eventual-consistency or throttling during reads; IAM permission changes; offset file truncated by a concurrent writer.","solutions":["Verify the offset file exists at initialOffsetLocation and is readable by the query identity.","Restore/repair the checkpoint location (recreate from backup) or restart the query with a fresh checkpoint if offsets can be replayed.","Inspect the wrapped IOException cause for transient storage errors and add retry/throttling configuration for S3/HDFS.","Avoid external cleanup of checkpoint directories used by live streaming queries."],"exampleFix":"// before\nStreamingOffset offset = stream.initialOffset();\n// after: guard with existence check and clear failure message\nInputFile f = fileIO.newInputFile(initialOffsetLocation);\nif (!f.exists()) { throw new IllegalStateException(\"Offset file missing, restart query or restore checkpoint: \" + initialOffsetLocation); }\nStreamingOffset offset = stream.initialOffset();","handlingStrategy":"try-catch","validationCode":"InputFile f = fileIO.newInputFile(initialOffsetLocation);\nif (!f.exists()) {\n  throw new IllegalStateException(\"Offset file missing at \" + initialOffsetLocation);\n}","typeGuard":null,"tryCatchPattern":"try { offset = stream.initialOffset(); } catch (UncheckedIOException e) {\n  if (e.getCause() instanceof FileNotFoundException) { restartQueryWithFreshCheckpoint(); }\n  else { retryWithBackoff(e); }\n}","preventionTips":["Protect checkpoint directories from external retention/cleanup jobs","Restore offsets from checkpoint backups before restarting queries","Configure S3/HDFS read retries for transient failures"],"tags":["spark","structured-streaming","io","checkpoint"],"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"}