apache/iceberg · error · UnsupportedOperationException
Unknown field ordinal:
Error message
Unknown field ordinal:
What it means
V2Metadata.ManifestFileWrapper.get(pos) maps ordinals 0-14 to the V2 manifest-list schema (including partitions at 13 and key_metadata at 14). An out-of-range ordinal has no field and throws UnsupportedOperationException with the position, indicating the caller's struct shape does not match the V2 manifest schema.
Source
Thrown at core/src/main/java/org/apache/iceberg/V2Metadata.java:145
return wrapped.snapshotId();
case 7:
return wrapped.addedFilesCount();
case 8:
return wrapped.existingFilesCount();
case 9:
return wrapped.deletedFilesCount();
case 10:
return wrapped.addedRowsCount();
case 11:
return wrapped.existingRowsCount();
case 12:
return wrapped.deletedRowsCount();
case 13:
return wrapped.partitions();
case 14:
return wrapped.keyMetadata();
default:
throw new UnsupportedOperationException("Unknown field ordinal: " + pos);
}
}
@Override
public String path() {
return wrapped.path();
}
@Override
public long length() {
return wrapped.length();
}
@Override
public int partitionSpecId() {
return wrapped.partitionSpecId();
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Bound access by size() (14 for V2 manifest files) rather than hardcoded counts
- Verify pos maps to a MANIFEST_LIST_SCHEMA column before calling get
- Ensure V1 code paths use V1Metadata wrappers and V2 use V2Metadata wrappers
Example fix
// before
Object v = wrapper.get(15);
// after
if (pos >= 0 && pos < wrapper.size()) { Object v = wrapper.get(pos); } Defensive patterns
Strategy: validation
Validate before calling
if (pos < 0 || pos >= MANIFEST_LIST_SCHEMA.columns().size()) { throw new IllegalArgumentException("ordinal out of range for V2 manifest list schema"); } Type guard
boolean validV2ManifestPos(int pos) { return pos >= 0 && pos < MANIFEST_LIST_SCHEMA.columns().size(); } Try / catch
try { return wrapper.get(pos); } catch (UnsupportedOperationException e) { LOG.warn("bad ordinal {} for V2 manifest wrapper", pos); return null; } Prevention
- Bound reads with size() (14 columns for V2 manifest files)
- Update hardcoded indices when schema gains columns (partitions, key_metadata)
- Pair V1 code with V1Metadata and V2 code with V2Metadata
When it happens
Trigger: Calling get(pos) with pos < 0 or pos > 14 on a V2Metadata.ManifestFileWrapper, often from generic iteration code bounded by a V1 schema size or a wrong constant.
Common situations: Mixed-version code paths reading V1-sized structs against V2 wrappers; hardcoded indices that predate the partitions/key_metadata columns; reflection-based readers with stale schemas.
Related errors
- Unknown field ordinal:
- Field + name + not found in source schema
- Cannot parse type string to primitive: + typeString
- Invalid default value for %s: %s (must be null)
- Unknown field ordinal: ${basePos}
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/b81dcfbb61afd38f.
Report an issue: GitHub.