{"record":{"id":"acc48f7670304c5f","repo":"apache/iceberg","slug":"failed-writing-offset-to-s-acc48f","errorCode":null,"errorMessage":"Failed writing offset to: %s","messagePattern":"Failed writing offset to: (.+?)","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":null,"severity":"error","filePath":"spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/source/SparkMicroBatchStream.java","lineNumber":303,"sourceCode":"      }\n\n      table.refresh();\n      StreamingOffset offset = MicroBatchUtils.determineStartingOffset(table, fromTimestamp);\n\n      OutputFile outputFile = io.newOutputFile(initialOffsetLocation);\n      writeOffset(offset, outputFile);\n\n      return offset;\n    }\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":285,"sourceCodeEnd":318,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/source/SparkMicroBatchStream.java#L285-L318","documentation":"SparkMicroBatchStream persists the current StreamingOffset as a JSON file at the initial offset location so streaming queries can resume. If writing that offset file fails with an IOException, it is rethrown as UncheckedIOException with the target location. A failed offset write means the stream cannot checkpoint its progress.","triggerScenarios":"Writing the streaming offset file fails due to an IOException — unwritable/missing directory, out-of-space filesystem, permissions, or FileIO returning a broken output stream at the initialOffsetLocation.","commonSituations":"Checkpoint/offset directory deleted or permissions changed between runs; HDFS/S3 outages or token expiry when creating the offset file; disk full on the driver or local FS; misconfigured warehouse path.","solutions":["Verify the offset location directory exists and is writable by the Spark driver/executor, creating it if needed","Check storage backend health and credentials (HDFS availability, S3 keys/roles, disk space)","Inspect the chained IOException cause for the root storage error and fix that; then restart the streaming query from a valid checkpoint"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"File offsetDir = new File(initialOffsetLocation);\nif (!offsetDir.getParentFile().canWrite()) throw new IllegalStateException(\"Offset dir not writable\");","typeGuard":null,"tryCatchPattern":"try {\n  stream.writeOffset(offset);\n} catch (UncheckedIOException e) {\n  LOG.error(\"Offset write failed at {}\", e.getMessage(), e.getCause());\n  // remediate storage, then restart from checkpoint\n}","preventionTips":["Provision and monitor the offset/checkpoint directory with correct permissions","Monitor disk space and object-store health for the streaming location","Keep storage credentials valid for the lifetime of the streaming query"],"tags":["spark","streaming","io","checkpoint"],"backgroundTag":"file-write-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"}