apache/iceberg · error · IllegalArgumentException

Expected two ORC type descriptions for a map, got:

Error message

Expected two ORC type descriptions for a map, got: 

What it means

SparkOrcValueWriters.MapWriter requires exactly two ORC TypeDescriptions — one for keys and one for values — as ORC maps have exactly two child types. A size other than 2 indicates the ORC schema does not match the expected map layout. This IllegalArgumentException is an internal consistency check on the ORC type tree.

Solutions

  1. Confirm the ORC TypeDescription for the map column has exactly two children (key, value).
  2. Rewrite the data with a standard ORC writer to normalize the schema.
  3. Check the schema passed into SparkOrcWriter against the actual file schema.
  4. Align Iceberg and ORC library versions.
Defensive patterns

Strategy: validation

Validate before calling

org.apache.orc.TypeDescription mapType = schema.findSubtype("my_map");
if (mapType.getChildren().size() != 2) {
  throw new IllegalStateException("ORC map must have exactly two child types, got " + mapType.getChildren());
}

Type guard

static boolean isWellFormedOrcMap(org.apache.orc.TypeDescription t) {
  return t.getCategory() == org.apache.orc.TypeDescription.Category.MAP && t.getChildren().size() == 2;
}

Prevention

When it happens

Trigger: Constructing a MapWriter where the ORC map column's child type list has fewer or more than 2 entries, caused by a malformed or mismatched ORC schema handed to SparkOrcWriter.

Common situations: Reading/writing ORC produced by non-standard writers, custom schema stitching, or version-skew producing a map schema with unexpected children.

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

Appendix: source

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

    @Override
    public Stream<FieldMetrics<?>> metrics() {
      return writer.metrics();
    }
  }

  private static class MapWriter<K, V> implements OrcValueWriter<MapData> {
    private final OrcValueWriter<K> keyWriter;
    private final OrcValueWriter<V> valueWriter;
    private final SparkOrcWriter.FieldGetter<K> keyFieldGetter;
    private final SparkOrcWriter.FieldGetter<V> valueFieldGetter;

    @SuppressWarnings("unchecked")
    MapWriter(
        OrcValueWriter<K> keyWriter,
        OrcValueWriter<V> valueWriter,
        List<TypeDescription> orcTypes) {
      if (orcTypes.size() != 2) {
        throw new IllegalArgumentException(
            "Expected two ORC type descriptions for a map, got: " + orcTypes);
      }
      this.keyWriter = keyWriter;
      this.valueWriter = valueWriter;
      this.keyFieldGetter =
          (SparkOrcWriter.FieldGetter<K>) SparkOrcWriter.createFieldGetter(orcTypes.get(0));
      this.valueFieldGetter =
          (SparkOrcWriter.FieldGetter<V>) SparkOrcWriter.createFieldGetter(orcTypes.get(1));
    }

    @Override
    public void nonNullWrite(int rowId, MapData map, ColumnVector output) {
      ArrayData key = map.keyArray();
      ArrayData value = map.valueArray();
      MapColumnVector cv = (MapColumnVector) output;
      // record the length and start of the list elements
      cv.lengths[rowId] = value.numElements();
      cv.offsets[rowId] = cv.childCount;

View on GitHub (pinned to 86d9c8fc54)