apache/iceberg · error · UnsupportedOperationException
does not support cardinality
Error message
${getClass().getName()} does not support cardinality What it means
PositionDeleteIndex.cardinality() returns the number of positions in the index, but the interface default throws UnsupportedOperationException because not every implementation can compute cardinality cheaply (or at all). Callers such as toBlob (serialization) and deletion-vector construction require it.
Solutions
- Override cardinality() in the implementation to return the true count of positions
- Use BitmapPositionDeleteIndex (or another full implementation) wherever deletion vectors will be produced
- At call sites, only request cardinality from indexes created from delete files whose format supports counting positions
Example fix
// before
@Override public long cardinality() { throw new UnsupportedOperationException(...); }
// after
@Override public long cardinality() { return bitmap.getLongCardinality(); } Defensive patterns
Strategy: type-guard
Validate before calling
if (index instanceof BitmapPositionDeleteIndex) { long n = index.cardinality(); } else { /* fall back to delete-file metadata */ } Type guard
boolean supportsCardinality(PositionDeleteIndex idx) { return !(idx.getClass().getSimpleName().startsWith("Default") && isStub(idx)); } Try / catch
try { return index.cardinality(); } catch (UnsupportedOperationException e) { return deleteFiles.stream().mapToLong(DeleteFile::contentSizeInBytes).count(); } Prevention
- Only request cardinality from indexes backing deletion-vector production
- Derive counts from DeleteFile metadata where possible instead of in-memory indexes
- Test custom index implementations against the full PositionDeleteIndex contract
When it happens
Trigger: Calling cardinality() on an implementation that has not overridden the default — e.g. when serializing an index to a blob, building a deletion vector (dv), or in assertEqual and tests that check index size.
Common situations: Using a custom or partial PositionDeleteIndex implementation in a code path that builds DeletionVectors, which always need cardinality; e.g. plugging a custom index into DV-based table maintenance.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- does not implement length
- does not support forEach
- does not support serialize
- Unsupported delete granularity
- AboveMax has no value
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/efaf18f1e52330e8.
Report an issue: GitHub.
Appendix: source
Thrown at core/src/main/java/org/apache/iceberg/deletes/PositionDeleteIndex.java:93
*/
default void forEach(LongConsumer consumer) {
if (isNotEmpty()) {
throw new UnsupportedOperationException(getClass().getName() + " does not support forEach");
}
}
/**
* Returns delete files that this index was created from or an empty collection if unknown.
*
* @return delete files that this index was created from
*/
default Collection<DeleteFile> deleteFiles() {
return ImmutableList.of();
}
/** Returns the cardinality of this index. */
default long cardinality() {
throw new UnsupportedOperationException(getClass().getName() + " does not support cardinality");
}
/**
* Serializes this index.
*
* @return a buffer containing the serialized index
*/
default ByteBuffer serialize() {
throw new UnsupportedOperationException(getClass().getName() + " does not support serialize");
}
/**
* Deserializes a position delete index.
*
* @param bytes an array containing the serialized index
* @param deleteFile the delete file that the index is created for
* @return the deserialized index
*/View on GitHub (pinned to 86d9c8fc54)