apache/iceberg · error · IllegalStateException

File length unknown, creating an AesGcmInputFile is not safe

Error message

File length unknown, creating an AesGcmInputFile is not safe

What it means

AesGcmOutputFile.toInputFile() always throws IllegalStateException because an encrypted output file's length is unknown until it is closed and committed; creating an InputFile view would be unsafe. This is an intentional guard, not a recoverable failure.

Source

Thrown at core/src/main/java/org/apache/iceberg/encryption/AesGcmOutputFile.java:53

  @Override
  public PositionOutputStream create() {
    return new AesGcmOutputStream(targetFile.create(), dataKey, fileAADPrefix);
  }

  @Override
  public PositionOutputStream createOrOverwrite() {
    return new AesGcmOutputStream(targetFile.createOrOverwrite(), dataKey, fileAADPrefix);
  }

  @Override
  public String location() {
    return targetFile.location();
  }

  @Override
  public InputFile toInputFile() {
    throw new IllegalStateException("File length unknown, creating an AesGcmInputFile is not safe");
  }
}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Close/complete the output and obtain an InputFile from the underlying FileIO using the known final file length (e.g. io.newInputFile(location)) instead of toInputFile()
  2. Delay any read of the encrypted file until after the write is finished and its length is known
  3. Restructure the commit flow to use the resulting DataFile/DeleteFile metadata (with file size) rather than converting the output file

Example fix

// before
InputFile in = aesGcmOutputFile.toInputFile();
// after
outputFile.close(); // complete the write first
InputFile in = fileIO.newInputFile(location);
Defensive patterns

Strategy: fallback

Validate before calling

// cannot be validated on the object itself; ensure write is complete before reading
if (!outputComplete) { throw new IllegalStateException("Output file not finalized; cannot read"); }

Try / catch

try { return out.toInputFile(); } catch (IllegalStateException e) { return fileIO.newInputFile(out.location()); /* after close */ }

Prevention

When it happens

Trigger: Calling toInputFile() on an AesGcmOutputFile, e.g. generic code that converts any OutputFile to an InputFile (such as overwrite/commit plumbing that immediately re-reads the written file).

Common situations: Frameworks that unconditionally call toInputFile() on freshly written outputs, or code that tries to read an encrypted file while it is still being written.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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