apache/iceberg · error · UnsupportedOperationException

Unsupported stats offset:

Error message

Unsupported stats offset: 

What it means

FieldStatsStruct.getOffset maps stat offsets (UPPER_BOUND, TIGHT_BOUNDS, VALUE_COUNT, NULL_VALUE_COUNT, NAN_VALUE_COUNT, AVG_VALUE_SIZE) to field values; an unrecognized offset throws UnsupportedOperationException('Unsupported stats offset: ' + offset). Since offsets come from posToOffset (built from a projected stats struct schema), this indicates the projection contains a field position with no corresponding stats offset.

Source

Thrown at core/src/main/java/org/apache/iceberg/FieldStatsStruct.java:195

  public Integer avgValueSizeInBytes() {
    return avgValueSize;
  }

  @Override
  public int size() {
    return struct.fields().size();
  }

  private Object getOffset(int offset) {
    return switch (offset) {
      case StatsUtil.LOWER_BOUND_OFFSET -> lowerBound();
      case StatsUtil.UPPER_BOUND_OFFSET -> upperBound();
      case StatsUtil.TIGHT_BOUNDS_OFFSET -> tightBounds;
      case StatsUtil.VALUE_COUNT_OFFSET -> valueCount;
      case StatsUtil.NULL_VALUE_COUNT_OFFSET -> nullValueCount;
      case StatsUtil.NAN_VALUE_COUNT_OFFSET -> nanValueCount;
      case StatsUtil.AVG_VALUE_SIZE_OFFSET -> avgValueSize;
      default -> throw new UnsupportedOperationException("Unsupported stats offset: " + offset);
    };
  }

  @Override
  public <C> C get(int pos, Class<C> javaClass) {
    return javaClass.cast(getOffset(posToOffset[pos]));
  }

  private void setOffset(int offset, Object value) {
    switch (offset) {
      case StatsUtil.LOWER_BOUND_OFFSET -> setLowerBound(value);
      case StatsUtil.UPPER_BOUND_OFFSET -> setUpperBound(value);
      case StatsUtil.TIGHT_BOUNDS_OFFSET -> this.tightBounds = (Boolean) value;
      case StatsUtil.VALUE_COUNT_OFFSET -> this.valueCount = (Long) value;
      case StatsUtil.NULL_VALUE_COUNT_OFFSET -> this.nullValueCount = (Long) value;
      case StatsUtil.NAN_VALUE_COUNT_OFFSET -> this.nanValueCount = (Long) value;
      case StatsUtil.AVG_VALUE_SIZE_OFFSET -> this.avgValueSize = (Integer) value;
      default -> throw new UnsupportedOperationException("Unsupported stats offset: " + offset);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Ensure the reader and writer Iceberg versions agree on the stats file schema; re-generate the statistics file with the current version.
  2. Verify posToOffset is built by StatsUtil.posToOffset(...) from the same type used to create the FieldStatsStruct, not by custom code.
  3. Print the offending offset and compare against StatsUtil offset constants to identify the unexpected field.
  4. Upgrade Iceberg if the stats file uses a newer schema version than the reader supports.

Example fix

// before: hand-built offset array
int[] posToOffset = {0, 1, 2, 99}; // 99 is not a known stats offset
// after: derive offsets from StatsUtil
int[] posToOffset = StatsUtil.posToOffset(partitionType, statsType);
Defensive patterns

Strategy: validation

Validate before calling

for (int offset : posToOffset) {
  if (!StatsUtil.isKnownOffset(offset)) {
    throw new IllegalArgumentException("Unsupported stats offset in projection: " + offset);
  }
}

Try / catch

try {
  C v = statsStruct.get(pos, javaClass);
} catch (UnsupportedOperationException e) {
  if (e.getMessage().startsWith("Unsupported stats offset")) {
    // regenerate the statistics projection with the current StatsUtil
  } else throw e;
}

Prevention

When it happens

Trigger: Calling get(pos, Class) where posToOffset[pos] was computed from a partition/field-stats schema that includes a field outside the known stats offsets — typically a malformed projection produced by StatsUtil when the schema and stats file version disagree.

Common situations: Reading a statistics file written by a different Iceberg version whose StatsUtil offsets changed; custom code constructing posToOffset manually; partition fields added in newer spec versions but the reader is older.

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/80ab8e2d01c29f7c. Report an issue: GitHub.