apache/iceberg · error · UnsupportedOperationException
Unknown field ordinal:
Error message
Unknown field ordinal:
What it means
ManifestFileWrapper.get(pos) maps fixed ordinals 0-11 to V1 manifest-list schema columns. An ordinal outside that range has no corresponding field, so the wrapper throws UnsupportedOperationException with the offending pos. This indicates the caller is using a struct position that does not exist in the V1 manifest list schema.
Source
Thrown at core/src/main/java/org/apache/iceberg/V1Metadata.java:103
return snapshotId();
case 4:
return addedFilesCount();
case 5:
return existingFilesCount();
case 6:
return deletedFilesCount();
case 7:
return partitions();
case 8:
return addedRowsCount();
case 9:
return existingRowsCount();
case 10:
return deletedRowsCount();
case 11:
return 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
- Use pos values only within 0-11 for V1 manifest files; derive the bound from size() rather than hardcoding
- Check you are not reading a V2-schema field from a V1 wrapper; use V2Metadata wrappers for V2 tables
- Inspect the pos value in the message and map it against MANIFEST_LIST_SCHEMA.columns()
Example fix
// before Object v = wrapper.get(13); // V2-only ordinal // after Object v = wrapper.get(pos < wrapper.size() ? pos : -1); // guard by size()
Defensive patterns
Strategy: validation
Validate before calling
if (pos < 0 || pos >= MANIFEST_LIST_SCHEMA.columns().size()) { throw new IllegalArgumentException("ordinal out of range for manifest list schema"); } Type guard
boolean validManifestPos(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 V1 manifest wrapper", pos); return null; } Prevention
- Derive field bounds from size(), never hardcode ordinals
- Check table format version before reading version-specific fields
- Map field names via Types.NestedField lookups instead of positions
When it happens
Trigger: Calling get(pos) with pos < 0 or pos > 11 on a V1Metadata.ManifestFileWrapper, typically from generic StructLike iteration code that assumes a different schema version or struct shape.
Common situations: Code written against the V2 manifest schema (extra columns like partitions/sequence numbers) applied to a V1 table's manifest wrappers; off-by-one loops over struct fields using a wrong size constant.
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/d181cb7b34bb1d45.
Report an issue: GitHub.