apache/iceberg · error · IllegalArgumentException

Cannot convert Number to variant (unknown type)

Error message

Cannot convert Number to variant (unknown type): ${number.getClass().getName()}

What it means

The Number-to-Variant conversion in RecordConverter throws this IllegalArgumentException when a Number is neither Byte, Short, Integer, Long, Float, Double, BigDecimal, nor BigInteger — i.e. an unknown Number subtype the converter doesn't map to a Variant primitive.

Solutions

  1. Convert the value to a standard type (Integer, Long, Double, BigDecimal) before the sink
  2. Normalize exotic Numbers with an SMT (e.g. toLong/toDouble)
  3. Extend RecordConverter and override objectToVariantValue to handle the specific Number subclass
  4. Fix the deserializer to emit standard Java numeric boxed types

Example fix

// before
value = java.util.concurrent.atomic.AtomicLong(42) // unknown Number type
// after
value = atomicLong.longValue() // plain Long supported by Variants.of
Defensive patterns

Strategy: type-guard

Validate before calling

static boolean isStandardNumber(Object v) {
  return v instanceof Byte || v instanceof Short || v instanceof Integer || v instanceof Long
      || v instanceof Float || v instanceof Double
      || v instanceof java.math.BigDecimal || v instanceof java.math.BigInteger;
}

Type guard

static Number toStandardNumber(Number n) {
  if (isStandardNumber(n)) return n;
  return java.math.BigDecimal.valueOf(n.doubleValue()); // normalize exotic Number
}

Try / catch

try {
  converter.convertValue(num, Types.VariantType.get());
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Cannot convert Number to variant")) {
    log.error("Unknown Number subclass: " + e.getMessage());
    // retry with ((Number) value).longValue() or new BigDecimal(value.toString())
  }
}

Prevention

When it happens

Trigger: A custom Number subclass (e.g. AtomicLong, AtomicDouble, Guava/Kotlin numeric types, or a framework-specific numeric wrapper) reaches the Number branch of objectToVariantValue.

Common situations: SMTs that emit Atomic* types; deserializers producing exotic numeric wrappers; custom value classes extending Number passed through schemaless records.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at kafka-connect/kafka-connect/src/main/java/org/apache/iceberg/connect/data/RecordConverter.java:802

    if (number instanceof Integer integer) {
      return Variants.of(integer);
    }
    if (number instanceof Long longValue) {
      return Variants.of(longValue);
    }
    if (number instanceof Float floatValue) {
      return Variants.of(floatValue);
    }
    if (number instanceof Double doubleValue) {
      return Variants.of(doubleValue);
    }
    if (number instanceof Byte byteValue) {
      return Variants.of(byteValue);
    }
    if (number instanceof Short shortValue) {
      return Variants.of(shortValue);
    }
    throw new IllegalArgumentException(
        "Cannot convert Number to variant (unknown type): " + number.getClass().getName());
  }

  @SuppressWarnings("JavaUtilDate")
  private OffsetDateTime convertOffsetDateTime(Object value) {
    if (value instanceof Number) {
      long millis = ((Number) value).longValue();
      return DateTimeUtil.timestamptzFromMicros(millis * 1000);
    } else if (value instanceof String) {
      return parseOffsetDateTime((String) value);
    } else if (value instanceof OffsetDateTime) {
      return (OffsetDateTime) value;
    } else if (value instanceof LocalDateTime) {
      return ((LocalDateTime) value).atOffset(ZoneOffset.UTC);
    } else if (value instanceof Date) {
      return DateTimeUtil.timestamptzFromMicros(((Date) value).getTime() * 1000);
    }
    throw new ConnectException(

View on GitHub (pinned to 86d9c8fc54)