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: ${orcTypes}

What it means

Iceberg's Spark ORC writer builds a ListWriter from the ORC type descriptions of a list column. ORC lists have exactly one element type, so if the planner hands the writer more than one (or zero) TypeDescription entries, the schema and the Iceberg list type are inconsistent and construction fails fast with this IllegalArgumentException.

Solutions

  1. Verify the ORC schema's list type has exactly one child type (list<T> with a single element subtype).
  2. Regenerate the ORC TypeDescription from the Iceberg schema via SparkSchemaUtil/TypeDescription.fromString instead of hand-building it.
  3. Check for schema evolution mismatches between the table's current schema and the file schema passed to the writer.

Example fix

// before
ListWriter(writer, Arrays.asList(elemTypeA, elemTypeB))
// after
ListWriter(writer, Collections.singletonList(elemType))
Defensive patterns

Strategy: validation

Validate before calling

List<TypeDescription> orcTypes = schema.getChildren();
if (orcTypes.size() != 1) {
  throw new IllegalArgumentException("list schema must have exactly one element type: " + schema);
}

Type guard

boolean isValidListSchema(TypeDescription t) {
  return t.getCategory() == TypeDescription.Category.LIST && t.getChildren().size() == 1;
}

Try / catch

try {
  writer = SparkOrcValueWriters.list(elemWriter, orcTypes);
} catch (IllegalArgumentException e) {
  throw new IllegalStateException("Bad ORC list schema: " + e.getMessage(), e);
}

Prevention

When it happens

Trigger: Writing a Spark DataFrame to an Iceberg ORC table where the ORC schema for a list<T> column yields a List<TypeDescription> whose size != 1 — e.g. a mismatched/mis-derived ORC file schema passed to SparkOrcValueWriters.list.

Common situations: Custom ORC schema construction or schema evolution bugs; mixing manually built TypeDescription trees with Iceberg types; writing to a table whose ORC schema was generated by another tool with malformed list types.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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

Appendix: source

Thrown at spark/v4.2/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)