apache/iceberg · error · UnsupportedOperationException

Unsupported primitive type:

Error message

Unsupported primitive type: 

What it means

ArrowSchemaUtil.convertToArrowField's primitive() switch handles Iceberg's supported primitive types (long, float, timestamps, nanos, date, etc.). Any primitive type that falls past the switch — e.g. an unhandled or newly added Iceberg primitive — triggers this UnsupportedOperationException during Iceberg-to-Arrow schema conversion.

Source

Thrown at arrow/src/main/java/org/apache/iceberg/arrow/ArrowSchemaUtil.java:184

          arrowType = new ArrowType.FixedSizeBinary(16);
          break;
        case TIMESTAMP:
          arrowType =
              new ArrowType.Timestamp(
                  TimeUnit.MICROSECOND,
                  ((Types.TimestampType) primitive).shouldAdjustToUTC() ? "UTC" : null);
          break;
        case TIMESTAMP_NANO:
          arrowType =
              new ArrowType.Timestamp(
                  TimeUnit.NANOSECOND,
                  ((Types.TimestampNanoType) primitive).shouldAdjustToUTC() ? "UTC" : null);
          break;
        case DATE:
          arrowType = new ArrowType.Date(DateUnit.DAY);
          break;
        default:
          throw new UnsupportedOperationException("Unsupported primitive type: " + primitive);
      }

      return new Field(
          currentField.name(),
          new FieldType(currentField.isOptional(), arrowType, null),
          Lists.newArrayList());
    }
  }
}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Upgrade iceberg-arrow to a version whose convertToArrowField handles your table's types.
  2. Check which primitive type is printed in the message and cast/filter it out before conversion, or project it to a supported type in the scan schema.
  3. Add a case for the type in ArrowSchemaUtil if you control the build.
Defensive patterns

Strategy: validation

Validate before calling

schema.columns().forEach(c -> { if (c.type().isPrimitiveType()) { switch (c.type().typeId()) { case LONG: case FLOAT: case DOUBLE: case DATE: case TIMESTAMP: case TIMESTAMP_NANO: case BOOLEAN: case STRING: case BINARY: break; default: throw new IllegalArgumentException("Unsupported: " + c.type()); } } });

Type guard

static boolean isArrowConvertible(Types.NestedField f) { switch (f.type().typeId()) { case LONG: case FLOAT: case DOUBLE: case DATE: case TIMESTAMP: case TIMESTAMP_NANO: case BOOLEAN: case STRING: case BINARY: return true; default: return false; } }

Try / catch

try { return ArrowSchemaUtil.convertToArrowField(field); } catch (UnsupportedOperationException e) { throw new IllegalStateException("Upgrade iceberg-arrow to support type: " + field.type(), e); }

Prevention

When it happens

Trigger: Calling ArrowSchemaUtil.convertToArrowField (or converting a schema containing) a primitive type not covered by the switch, such as a newer Iceberg type or an unexpected UnknownType.

Common situations: Iceberg/Arrow version skew where the Arrow adapter predates a new Iceberg type; custom Type implementations; tables with type variants not yet mapped in this converter.

Related errors


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