apache/iceberg · error · IllegalArgumentException

File length is null

Error message

File length is null

What it means

AesGcmInputFile.encryptedLength() returns the encrypted file length, but if the file was constructed without a known encrypted length (the constructor variant that leaves encryptedLength null), it throws IllegalArgumentException. Encrypted-length-dependent operations (like producing a positioned stream) cannot proceed without it.

Source

Thrown at core/src/main/java/org/apache/iceberg/encryption/AesGcmInputFile.java:51

   * @deprecated will be removed in 2.0.0 This API does not receive file length, and is therefore
   *     not safe
   */
  @Deprecated
  public AesGcmInputFile(InputFile sourceFile, byte[] dataKey, byte[] fileAADPrefix) {
    this(sourceFile, dataKey, fileAADPrefix, null);
  }

  public AesGcmInputFile(InputFile sourceFile, byte[] dataKey, byte[] fileAADPrefix, Long length) {
    this.sourceFile = sourceFile;
    this.dataKey = dataKey;
    this.fileAADPrefix = fileAADPrefix;
    this.encryptedLength = length;
    this.plaintextLength = null;
  }

  private long encryptedLength() {
    if (encryptedLength == null) {
      throw new IllegalArgumentException("File length is null");
    }

    return encryptedLength;
  }

  @Override
  public long getLength() {
    if (plaintextLength == null) {
      // Presumes all streams use hard-coded plaintext block size.
      plaintextLength = AesGcmInputStream.calculatePlaintextLength(encryptedLength());
    }

    return plaintextLength;
  }

  @Override
  public SeekableInputStream newStream() {
    long ciphertextLength = encryptedLength();

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Construct AesGcmInputFile with the encrypted file length (the constructor variant that sets it)
  2. Ensure the underlying FileIO can report the file size before opening the encrypted input file
  3. Guard call sites: check that length is known before requesting streams that depend on encrypted length

Example fix

// before
new AesGcmInputFile(rawFile, key, aad); // encrypted length unknown
// after
new AesGcmInputFile(rawFile, key, aad, rawFile.getLength());
Defensive patterns

Strategy: validation

Validate before calling

if (rawFile.getLength() <= 0) { throw new IllegalArgumentException("Encrypted length required for AesGcmInputFile"); }

Type guard

boolean hasKnownLength(InputFile f) { try { return f.getLength() > 0; } catch (Exception e) { return false; } }

Try / catch

try { stream = aesGcmInputFile.newStream(); } catch (IllegalArgumentException e) { /* length missing: obtain it and rebuild the file */ }

Prevention

When it happens

Trigger: Creating an AesGcmInputFile via the constructor that omits the encrypted length, then invoking a path that calls encryptedLength() (e.g. newStream or length calculations that need the encrypted size).

Common situations: Wrapping files whose length is not knowable upfront (e.g. non-seekable or streaming sources) into AesGcmInputFile, then treating them as seekable encrypted inputs.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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