apache/iceberg · error · UnsupportedOperationException

Unknown field ordinal:

Error message

Unknown field ordinal: 

What it means

DeletionVectorStruct.getByPos maps a fixed set of ordinals (0=location, 1=offset, 2=sizeInBytes, 3=cardinality, 4=keyMetadata) to struct field values. Any ordinal outside 0-4 triggers UnsupportedOperationException('Unknown field ordinal: ' + pos). This only happens if internal code requests a position that is not part of the deletion-vector struct schema, which normally cannot occur with a valid schema.

Source

Thrown at core/src/main/java/org/apache/iceberg/DeletionVectorStruct.java:120

  @Override
  public DeletionVectorStruct copy() {
    return new DeletionVectorStruct(this);
  }

  @Override
  protected <T> T internalGet(int pos, Class<T> javaClass) {
    return javaClass.cast(getByPos(pos));
  }

  private Object getByPos(int pos) {
    return switch (pos) {
      case 0 -> location;
      case 1 -> offset;
      case 2 -> sizeInBytes;
      case 3 -> cardinality;
      case 4 -> keyMetadata();
      default -> throw new UnsupportedOperationException("Unknown field ordinal: " + pos);
    };
  }

  @Override
  protected <T> void internalSet(int pos, T value) {
    switch (pos) {
        // always coerce to String for Serializable
      case 0 -> this.location = value.toString();
      case 1 -> this.offset = (Long) value;
      case 2 -> this.sizeInBytes = (Long) value;
      case 3 -> this.cardinality = (Long) value;
      case 4 -> this.keyMetadata = ByteBuffers.toByteArray((ByteBuffer) value);
      default -> {
        // ignore the object, it must be from a newer version of the format
      }
    }
  }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Verify the projection schema used to read the deletion vector struct contains exactly the 5 DV fields; regenerate the projection rather than reusing a cached one.
  2. Log the offending `pos` value and compare against the DV struct type (`MetadataTableType`/DeletionVector schema) to find the mismatched accessor.
  3. If you wrote custom accessor code, index fields by name via the schema instead of hard-coded ordinals.

Example fix

// before: positional access with a hand-built schema
Object v = dvStruct.get(pos, Object.class); // pos from arbitrary schema
// after: look up the ordinal from the actual DV schema
int pos = deletionVectorType.field(field.name()).fieldId() - firstFieldId;
Object v = dvStruct.get(pos, Object.class);
Defensive patterns

Strategy: type-guard

Validate before calling

if (pos < 0 || pos >= deletionVectorType.fields().size()) {
  throw new IllegalArgumentException("Invalid DV ordinal: " + pos);
}

Type guard

boolean isValidDvOrdinal(int pos) { return pos >= 0 && pos <= 4; }

Try / catch

try {
  Object v = dvStruct.get(pos, Object.class);
} catch (UnsupportedOperationException e) {
  if (e.getMessage().startsWith("Unknown field ordinal")) {
    // projection/schema mismatch: rebuild the projection from the DV type
  } else throw e;
}

Prevention

When it happens

Trigger: Calling internalGet/getByPos with a position >= 5 or negative, typically when the struct is accessed with a schema that does not match the deletion vector type (e.g. a stale or hand-built Types.StructType whose field count exceeds the deletion vector's 5 fields).

Common situations: Custom readers projecting extra fields onto the DV struct; schema evolution code reusing a cached projection across different struct types; internal misuse after upgrading Iceberg where the DV struct layout changed.

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


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/3cf08163bf5cfeef. Report an issue: GitHub.