apache/iceberg · error · UnsupportedOperationException
%s doesn't implement copyWithStats
Error message
%s doesn't implement copyWithStats
What it means
ContentFile.copyWithStats(Set<Integer>) is a default interface method that concrete File implementations must override to produce a copy filtered to the requested column stats. The default body throws UnsupportedOperationException naming the class that failed to implement it.
Source
Thrown at api/src/main/java/org/apache/iceberg/ContentFile.java:215
* Copies this file without file stats. Manifest readers can reuse file instances; use this method
* to copy data without stats when collecting files.
*
* @return a copy of this data file, without lower bounds, upper bounds, value counts, null value
* counts, nan value counts, or average value sizes
*/
F copyWithoutStats();
/**
* Copies this file with column stats only for specific columns. Manifest readers can reuse file
* instances; use this method to copy data with stats only for specific columns when collecting
* files.
*
* @param requestedColumnIds column IDs for which to keep stats.
* @return a copy of data file, with lower bounds, upper bounds, value counts, null value counts,
* nan value counts, and average value sizes for only specific columns.
*/
default F copyWithStats(Set<Integer> requestedColumnIds) {
throw new UnsupportedOperationException(
this.getClass().getName() + " doesn't implement copyWithStats");
}
/**
* Copies this file (potentially without file stats). Manifest readers can reuse file instances;
* use this method to copy data when collecting files from tasks.
*
* @param withStats Will copy this file without file stats if set to <code>false</code>.
* @return a copy of this data file. If <code>withStats</code> is set to <code>false</code> the
* file will not contain lower bounds, upper bounds, value counts, null value counts, nan
* value counts, or average value sizes
*/
default F copy(boolean withStats) {
return withStats ? copy() : copyWithoutStats();
}
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Upgrade iceberg-core/parquet modules so a full implementation (e.g. GenericDataFile) is used and consistent with iceberg-api.
- If you wrote a custom ContentFile implementation, implement copyWithStats to copy the file while filtering lower/upper bounds, value counts, null/nan counts, and avg sizes to requestedColumnIds.
- In tests, use real implementations (GenericDataFile.copy) rather than partial stubs.
Example fix
// before
class MyDataFile implements DataFile { /* no copyWithStats */ }
// after
@Override
public MyDataFile copyWithStats(Set<Integer> requestedColumnIds) {
MyDataFile copy = copy();
copy.setColumnStats filtered to requestedColumnIds;
return copy;
} Defensive patterns
Strategy: type-guard
Validate before calling
if (!(file instanceof GenericDataFile)) {
// may not implement copyWithStats — use file.copy() or upgrade
} Try / catch
DataFile copy;
try {
copy = file.copyWithStats(colIds);
} catch (UnsupportedOperationException e) {
copy = file.copy(); // degrade: full copy without stat filtering
} Prevention
- Keep iceberg-api and implementation jars at the same version.
- Use real implementations (GenericDataFile) not stubs in tests.
- Implement copyWithStats in any custom ContentFile class.
- Prefer files produced by manifest readers, which support stat copies.
When it happens
Trigger: Calling copyWithStats on a ContentFile implementation (custom, mock, or older library version) that has not overridden copyWithStats; using a DataFile built by hand rather than from a manifest reader.
Common situations: Custom FileIO/engine integrations subclassing a base file class that predates copyWithStats; test mocks returning plain DataFile instances; version skew between iceberg-api and iceberg-core jars.
Related errors
- %s doesn't implement validateFilesExist
- %s doesn't implement cleanupLevel
- %s doesn't implement cleanExpiredMetadata
- Updating statistics is not supported by + getClass().getName
- Updating statistics is not supported by + getClass().getName
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/b1c8bef2dc3928f7.
Report an issue: GitHub.