apache/iceberg · critical · UncheckedIOException

Failed reading offset from: %s

Error message

Failed reading offset from: %s

What it means

Wrapping error in SparkMicroBatchStream.readOffset: reading the JSON-serialized StreamingOffset back from the checkpoint location failed with an IOException, rethrown as UncheckedIOException naming the source file (%s). Typically a missing/truncated offset file or storage read failure.

Source

Thrown at spark/v4.1/spark/src/main/java/org/apache/iceberg/spark/source/SparkMicroBatchStream.java:312

    }

    private void writeOffset(StreamingOffset offset, OutputFile file) {
      try (OutputStream outputStream = file.create()) {
        BufferedWriter writer =
            new BufferedWriter(new OutputStreamWriter(outputStream, StandardCharsets.UTF_8));
        writer.write(offset.json());
        writer.flush();
      } catch (IOException ioException) {
        throw new UncheckedIOException(
            String.format("Failed writing offset to: %s", initialOffsetLocation), ioException);
      }
    }

    private StreamingOffset readOffset(InputFile file) {
      try (InputStream in = file.newStream()) {
        return StreamingOffset.fromJson(in);
      } catch (IOException ioException) {
        throw new UncheckedIOException(
            String.format("Failed reading offset from: %s", initialOffsetLocation), ioException);
      }
    }
  }
}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Inspect caused-by for the actual IO/parse error
  2. Restore or clear the corrupt offset file and restart the stream from a fresh checkpoint
  3. Verify checkpoint location integrity and credentials
  4. Recreate the streaming query checkpoint if the offset is unrecoverable
Defensive patterns

Strategy: try-catch

Validate before calling

// before reading, verify offset file exists and is non-empty
if (file == null || file.getLength() == 0) { /* reset to initial offset */ }

Try / catch

try { offset = stream.readOffset(file); } catch (UncheckedIOException e) { /* fall back to initial offset or restore checkpoint from backup */ }

Prevention

When it happens

Trigger: The offset InputFile exists but newStream() or StreamingOffset.fromJson fails — truncated/corrupt offset file, storage errors, or the file vanished mid-read.

Common situations: Corrupted checkpoint offsets after failed writes; concurrent modification of the checkpoint location; object-store eventual consistency or deleted offset files.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/d55d7749a60c60c7. Report an issue: GitHub.