apache/iceberg · error · UnsupportedOperationException
%s doesn't implement cleanExpiredMetadata
Error message
%s doesn't implement cleanExpiredMetadata
What it means
ExpireSnapshots.cleanExpiredMetadata is a default interface method that throws unless the implementation supports deleting unused metadata (old partition specs, schemas). The default preserves compatibility with implementations written before the option existed.
Source
Thrown at api/src/main/java/org/apache/iceberg/ExpireSnapshots.java:161
* <p>Consider {@link CleanupLevel#NONE} when data and metadata files may be more efficiently
* removed using a distributed framework through the actions API.
*
* @param level the cleanup level to use for expired snapshots
* @return this for method chaining
*/
default ExpireSnapshots cleanupLevel(CleanupLevel level) {
throw new UnsupportedOperationException(
this.getClass().getName() + " doesn't implement cleanupLevel");
}
/**
* Enable cleaning up unused metadata, such as partition specs, schemas, etc.
*
* @param clean remove unused partition specs, schemas, or other metadata when true
* @return this for method chaining
*/
default ExpireSnapshots cleanExpiredMetadata(boolean clean) {
throw new UnsupportedOperationException(
this.getClass().getName() + " doesn't implement cleanExpiredMetadata");
}
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Upgrade the ExpireSnapshots implementation to one supporting cleanExpiredMetadata
- Disable the metadata cleanup option so the default method is never invoked
- If you own the implementation, override cleanExpiredMetadata(boolean) and wire it into the expire plan
Example fix
// before expireSnapshots.cleanExpiredMetadata(true).execute(); // after expireSnapshots.execute(); // metadata cleanup unsupported by this implementation
Defensive patterns
Strategy: try-catch
Validate before calling
// gate metadata cleanup on implementation support cleanMetadata = cleanMetadata && implementationSupportsMetadataCleanup;
Try / catch
try {
expireSnapshots.cleanExpiredMetadata(true);
} catch (UnsupportedOperationException e) {
LOG.warn("cleanExpiredMetadata unsupported, continuing without it");
} Prevention
- Only enable clean-expired-metadata options with implementations that support them
- Catch UnsupportedOperationException around chained option setters
- Test expire actions against the exact catalog/engine versions in production
When it happens
Trigger: Calling expireSnapshots.cleanExpiredMetadata(true) on an implementation that does not override it; invoked from expireFiles/call paths when configuration requests metadata cleanup on an unsupported implementation.
Common situations: Enabling metadata cleanup on an older Spark/Flink action version or a custom catalog implementation; property-driven configuration (e.g. clean-expired-metadata) reaching a legacy implementation.
Related errors
- %s doesn't implement cleanupLevel
- %s doesn't implement copyWithStats
- %s doesn't implement validateFilesExist
- Can't retrieve values from an empty struct
- Can't modify an empty struct
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/560e813ab6afeeeb.
Report an issue: GitHub.