apache/hadoop · error · HadoopIllegalArgumentException

non-array value of class {} not allowed

Error message

non-array value of class {} not allowed

What it means

checkArray()'s second guard in set(Object) throws HadoopIllegalArgumentException when the value is non-null but not an array at all. ArrayPrimitiveWritable must derive componentType via value.getClass().getComponentType(), which returns null for non-arrays, so any scalar, collection, or object is rejected.

Source

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

          + 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()) {
      throw new HadoopIllegalArgumentException("non-array value of class "
          + value.getClass() + " not allowed");             
    }
  }
  
  /**
   * Construct an empty instance, for use during Writable read
   */
  public ArrayPrimitiveWritable() {
    //empty constructor
  }
  
  /**
   * Construct an instance of known type but no value yet
   * for use with type-specific wrapper classes.
   *
   * @param componentType componentType.
   */
  public ArrayPrimitiveWritable(Class<?> componentType) {

View on GitHub (pinned to 2add963021)

Solutions

  1. Wrap scalars in a one-element primitive array: set(new int[] {v}).
  2. Convert collections to primitive arrays first (e.g. ints via stream().mapToInt(...).toArray()).
  3. For non-primitive elements use ArrayWritable or a custom Writable.

Example fix

// before
List<Integer> nums = ...;
w.set(nums); // throws: not an array

// after
int[] arr = nums.stream().mapToInt(Integer::intValue).toArray();
w.set(arr);
Defensive patterns

Strategy: type-guard

Validate before calling

Object v = ...;
if (v == null || !v.getClass().isArray()) {
  throw new IllegalArgumentException("Expected an array, got: " + (v == null ? "null" : v.getClass().getName()));
}

Type guard

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

Prevention

When it happens

Trigger: set(Integer.valueOf(42)), set("abc"), set(Arrays.asList(1,2,3)), set(new ArrayList<double[]>()) — anything where value.getClass().isArray() is false.

Common situations: Passing a single primitive instead of a one-element array; passing a List from business code assuming Hadoop converts it; passing a boxed value from a generic <T> method with T=Integer rather than T=Integer[].

Related errors


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