apache/hadoop · error · HadoopIllegalArgumentException

input array component type {} is not a candidate primitive t

Error message

input array component type {} is not a candidate primitive type

What it means

ArrayPrimitiveWritable only supports arrays whose component type is one of the eight Java primitives, verified by lookup in the PRIMITIVE_NAMES map (populated with boolean/char/byte/short/int/long/float/double). checkPrimitive() throws this HadoopIllegalArgumentException when the component type is non-null but its name is not in that map — i.e. it is a reference type or void.

Source

Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/io/ArrayPrimitiveWritable.java:76

    PRIMITIVE_NAMES.put(byte.class.getName(), byte.class);
    PRIMITIVE_NAMES.put(char.class.getName(), char.class);
    PRIMITIVE_NAMES.put(short.class.getName(), short.class);
    PRIMITIVE_NAMES.put(int.class.getName(), int.class);
    PRIMITIVE_NAMES.put(long.class.getName(), long.class);
    PRIMITIVE_NAMES.put(float.class.getName(), float.class);
    PRIMITIVE_NAMES.put(double.class.getName(), double.class);
  }
  
  private static Class<?> getPrimitiveClass(String className) {
    return PRIMITIVE_NAMES.get(className);
  }
  
  private static void checkPrimitive(Class<?> componentType) {
    if (componentType == null) { 
      throw new HadoopIllegalArgumentException("null component type not allowed"); 
    }
    if (! PRIMITIVE_NAMES.containsKey(componentType.getName())) {
      throw new HadoopIllegalArgumentException("input array component type "
          + componentType.getName() + " is not a candidate primitive type");
    }
  }
  
  private void checkDeclaredComponentType(Class<?> componentType) {
    if ((declaredComponentType != null) 
        && (componentType != declaredComponentType)) {
      throw new HadoopIllegalArgumentException("input array component type "
          + componentType.getName() + " does not match declared type "
          + declaredComponentType.getName());     
    }
  }
  
  private static void checkArray(Object value) {
    if (value == null) { 
      throw new HadoopIllegalArgumentException("null value not allowed"); 
    }
    if (! value.getClass().isArray()) {

View on GitHub (pinned to 2add963021)

Solutions

  1. Use a primitive array (int[], long[], double[]...) not a boxed or Object array.
  2. For String[] or Writable[] arrays, use org.apache.hadoop.io.ArrayWritable with Text.class or your Writable class instead.
  3. If data arrives boxed, convert once: int[] prim = ArrayUtils.toPrimitive(boxedArray); before wrapping.
  4. For mixed/non-primitive element types, implement a custom Writable.

Example fix

// before
Writable w = new ArrayPrimitiveWritable(new Integer[] {1, 2, 3}); // throws

// after
Writable w = new ArrayPrimitiveWritable(new int[] {1, 2, 3});
Defensive patterns

Strategy: type-guard

Validate before calling

Object v = ...;
if (v == null || !v.getClass().isArray()
    || !v.getClass().getComponentType().isPrimitive()) {
  throw new IllegalArgumentException("Value must be a primitive array, got: " + (v == null ? "null" : v.getClass()));
}

Type guard

static boolean isPrimitiveArray(Object v) {
  return v != null && v.getClass().isArray()
      && v.getClass().getComponentType().isPrimitive();
}

Prevention

When it happens

Trigger: Calling set(new String[n]), set(new Object[n]), set(new Integer[n]) (boxed array), or new ArrayPrimitiveWritable(String[].class). The component type extracted by value.getClass().getComponentType() or passed explicitly is a class, not a primitive TYPE.

Common situations: Porting code that boxed primitives (Integer[] instead of int[]) for generics reasons; passing a Writable[] or Text[] assuming ArrayWritable-like behavior; autoboxing collections via toArray() producing Object[] or boxed arrays.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/61374a520263ea97. Report an issue: GitHub.