apache/iceberg · error · RuntimeIOException

Failed to fetch file: %s

Error message

Failed to fetch file: %s

What it means

EagerInputFile.newStream wraps any IOException from fully reading the file into a RuntimeIOException with message 'Failed to fetch file: <location>'. It means the eager whole-file read into memory failed (missing file, permission problem, or mid-read IO error).

Source

Thrown at core/src/main/java/org/apache/iceberg/io/EagerInputFile.java:88

    return delegate.exists();
  }

  @Override
  public SeekableInputStream newStream() {
    byte[] bytes = new byte[(int) length];
    try (SeekableInputStream src = delegate.newStream()) {
      IOUtil.readFully(src, bytes, 0, bytes.length);
      // reads from the already open stream; no additional request
      if (src.read() != -1) {
        throw new IOException(
            "Incorrect length provided for file "
                + delegate.location()
                + ", given a length of "
                + length
                + " and did not reach the end of stream");
      }
    } catch (IOException e) {
      throw new RuntimeIOException(e, "Failed to fetch file: %s", delegate.location());
    }
    return new EagerInputStream(bytes);
  }

  /** An {@link EagerInputFile} that preserves the delegate's Hadoop configuration. */
  private static class EagerInputFileConfigurable extends EagerInputFile
      implements HadoopConfigurable {

    private final HadoopConfigurable delegate;

    EagerInputFileConfigurable(InputFile delegate, long length) {
      super(delegate, length);
      Preconditions.checkArgument(
          delegate instanceof HadoopConfigurable,
          "Cannot create Hadoop Configurable Eager Input File because %s does not implement HadoopConfigurable",
          delegate.getClass().getName());
      this.delegate = (HadoopConfigurable) delegate;
    }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Check the wrapped cause; if 'Incorrect length provided...', fix the supplied length.
  2. Verify the file exists and is readable in storage.
  3. Retry; transient storage errors are common for eager full-file reads.
  4. If files are large, avoid eager loading and use a streaming InputFile to reduce failure surface and memory pressure.

Example fix

// before
InputFile eager = ContentCache.buildEagerInputFile(location, delegate); // may RuntimeIOException
// after
try {
  return eager.newStream();
} catch (RuntimeIOException e) {
  LOG.warn("Eager fetch failed for {}", location, e);
  return delegate.newStream(); // fall back to lazy streaming
}
Defensive patterns

Strategy: fallback

Validate before calling

if (!io.newInputFile(location).exists()) {
  throw new NotFoundException("File missing: " + location);
}

Try / catch

try {
  return eagerFile.newStream();
} catch (RuntimeIOException e) {
  LOG.warn("Eager fetch of {} failed, using streaming", location, e);
  return delegate.newStream();
}

Prevention

When it happens

Trigger: Calling newStream() on an EagerInputFile when the delegate stream cannot be opened or read fully (file absent, access denied, storage error) — including the incorrect-length IOException from the EOF check.

Common situations: Reading an object that was deleted/expired; wrong credentials or region for the bucket; network failure during bulk read; length mismatch from a stale length parameter.

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/e978af39112858fb. Report an issue: GitHub.