apache/iceberg · error · IllegalArgumentException

Cannot copy wrapped DataFile

Error message

Cannot copy wrapped DataFile

What it means

Delegates wraps a DataFile/DeleteFile to override identity-related methods while forwarding everything else to the wrapped file. Copy operations are unsupported on the wrapper because copies must not carry the wrapper semantics, so copy() always throws IllegalArgumentException.

Solutions

  1. Unwrap or copy the underlying file rather than the delegate (e.g. use ContentFileUtil.copy on the wrapped file).
  2. Restructure code so copies are made on concrete files before delegation.
  3. If you control the wrapping site, copy before wrapping.

Example fix

// before
DataFile copy = delegatedFile.copy();
// after
DataFile copy = ContentFileUtil.copy(wrapped, false, null);
Defensive patterns

Strategy: type-guard

Validate before calling

if (file.getClass().getName().contains("Delegates$")) {
  throw new IllegalStateException("copy the wrapped file, not the delegate");
}

Type guard

boolean isDelegate(ContentFile<?> f) { return f.getClass().getName().contains("Delegates$"); }

Try / catch

try { copy = file.copy(); } catch (IllegalArgumentException e) {
  copy = ContentFileUtil.copy(wrapped, false, null);
}

Prevention

When it happens

Trigger: Calling copy() on a DataFile obtained from contexts that return delegated files (e.g. certain index or scan wrappers) instead of an underlying BaseDataFile.

Common situations: Generic file-processing code that blindly calls copy() on every DataFile; passing delegated files into utilities that assume copyable concrete files.

Related errors


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

Appendix: source

Thrown at core/src/main/java/org/apache/iceberg/Delegates.java:287

    @Override
    public Long dataSequenceNumber() {
      return wrapped.dataSequenceNumber();
    }

    @Override
    public Long fileSequenceNumber() {
      return wrapped.fileSequenceNumber();
    }

    @Override
    public Long firstRowId() {
      return wrapped.firstRowId();
    }

    @Override
    public F copy() {
      throw new IllegalArgumentException("Cannot copy wrapped DataFile");
    }

    @Override
    public F copyWithStats(Set<Integer> requestedColumnIds) {
      throw new IllegalArgumentException("Cannot copy wrapped DataFile");
    }

    @Override
    public F copyWithoutStats() {
      throw new IllegalArgumentException("Cannot copy wrapped DataFile");
    }
  }
}

View on GitHub (pinned to 86d9c8fc54)