apache/iceberg · error · IllegalArgumentException

Expected one (and same) ORC type for list elements, got:

Error message

Expected one (and same) ORC type for list elements, got: 

What it means

SparkOrcValueWriters.ListWriter expects exactly one ORC TypeDescription describing the list's element type, since ORC lists have a single child type. Receiving a list of TypeDescriptions whose size differs from 1 means the ORC schema and the writer wiring disagree. This IllegalArgumentException is an internal invariant check guarding schema/writer mismatch.

Source

Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/data/SparkOrcValueWriters.java:137

  }

  private static class Decimal38Writer implements OrcValueWriter<Decimal> {

    @Override
    public void nonNullWrite(int rowId, Decimal decimal, ColumnVector output) {
      ((DecimalColumnVector) output)
          .vector[rowId].set(HiveDecimal.create(decimal.toJavaBigDecimal()));
    }
  }

  private static class ListWriter<T> implements OrcValueWriter<ArrayData> {
    private final OrcValueWriter<T> writer;
    private final SparkOrcWriter.FieldGetter<T> fieldGetter;

    @SuppressWarnings("unchecked")
    ListWriter(OrcValueWriter<T> writer, List<TypeDescription> orcTypes) {
      if (orcTypes.size() != 1) {
        throw new IllegalArgumentException(
            "Expected one (and same) ORC type for list elements, got: " + orcTypes);
      }
      this.writer = writer;
      this.fieldGetter =
          (SparkOrcWriter.FieldGetter<T>) SparkOrcWriter.createFieldGetter(orcTypes.get(0));
    }

    @Override
    public void nonNullWrite(int rowId, ArrayData value, ColumnVector output) {
      ListColumnVector cv = (ListColumnVector) output;
      // record the length and start of the list elements
      cv.lengths[rowId] = value.numElements();
      cv.offsets[rowId] = cv.childCount;
      cv.childCount = (int) (cv.childCount + cv.lengths[rowId]);
      // make sure the child is big enough
      growColumnVector(cv.child, cv.childCount);
      // Add each element
      for (int e = 0; e < cv.lengths[rowId]; ++e) {

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Verify the ORC TypeDescription for the list column has a single child (element type).
  2. Regenerate/rewrite the ORC schema with a standard writer.
  3. Check that the schema passed to SparkOrcWriter matches the actual file schema.
  4. Align Iceberg and ORC library versions.
Defensive patterns

Strategy: validation

Validate before calling

org.apache.orc.TypeDescription listType = schema.findSubtype("my_list");
if (listType.getChildren().size() != 1) {
  throw new IllegalStateException("ORC list must have exactly one child type, got " + listType.getChildren());
}

Type guard

static boolean isWellFormedOrcList(org.apache.orc.TypeDescription t) {
  return t.getCategory() == org.apache.orc.TypeDescription.Category.LIST && t.getChildren().size() == 1;
}

Prevention

When it happens

Trigger: Constructing a ListWriter where the ORC child types list for a list column does not contain exactly one entry, typically due to a corrupted or mismatched ORC schema passed into SparkOrcWriter.

Common situations: Custom writer wiring, ORC schema produced by a foreign/buggy writer, or version mismatches where the ORC file schema's list encoding differs from expected.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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