spring-projects/spring-framework · error · BeanInstantiationException

Illegal arguments for constructor

Error message

Illegal arguments for constructor

What it means

Thrown as BeanInstantiationException by instantiateClass(Constructor, args) at BeanUtils.java:217 when Constructor.newInstance raises IllegalArgumentException. This means the supplied argument array does not match the constructor's parameter types (wrong count, wrong type, or a primitive parameter given an incompatible/wrong wrapper). The pre-check at line 192 only guards the upper bound (args.length <= paramCount); it does not type-check.

Solutions

  1. Compare ctor.getParameterTypes() against your args' classes element-by-element before calling.
  2. Coerce each arg to its exact parameter type (convert Long->int, String->enum, etc.).
  3. Use MethodParameter / ResolvableType to resolve generics when types are parameterized.
  4. For nullable/primitive params, follow the same rule as BeanUtils: substitute DEFAULT_TYPE_VALUES for primitive nulls.

Example fix

// before
Constructor<User> c = User.class.getConstructor(String.class, int.class);
User u = BeanUtils.instantiateClass(c, "bob", 30L); // Long into int -> IAE

// after
User u = BeanUtils.instantiateClass(c, "bob", (int) 30L);
Defensive patterns

Strategy: validation

Validate before calling

Constructor<?> c = ...;
Class<?>[] pts = c.getParameterTypes();
if (args.length <= pts.length) {
    for (int i = 0; i < args.length; i++) {
        if (args[i] != null && !pts[i].isPrimitive()
                && !pts[i].isAssignableFrom(args[i].getClass())) {
            args[i] = conversionService.convert(args[i], pts[i]);
        }
    }
}
BeanUtils.instantiateClass(c, args);

Type guard

static boolean argsMatch(Constructor<?> c, Object[] args) {
    Class<?>[] pts = c.getParameterTypes();
    if (args.length > pts.length) return false;
    for (int i = 0; i < args.length; i++) {
        if (args[i] == null) continue;
        Class<?> need = pts[i].isPrimitive() ? wrap(pts[i]) : pts[i];
        if (!need.isAssignableFrom(args[i].getClass())) return false;
    }
    return true;
}

Try / catch

try {
    BeanUtils.instantiateClass(ctor, args);
} catch (BeanInstantiationException ex) {
    if (ex.getCause() instanceof IllegalArgumentException) {
        // coerce args to ctor.getParameterTypes() and retry once
    } else throw ex;
}

Prevention

When it happens

Trigger: Passing args whose runtime types are not assignable to the constructor's parameter types; passing a null for a primitive parameter where DEFAULT_TYPE_VALUES lookup did not apply (e.g. wrong index); passing more/wider args than expected after the length pre-check slipped through; boxed type mismatch like passing a Long to an int param.

Common situations: Programmatic bean instantiation where arguments are built dynamically; reflection-based mappers; converting user input to constructor args without type coercion; Kotlin default-arg handling when null is passed for a non-optional, non-primitive parameter that the framework mis-counts.

Related errors


AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09). Data as JSON: /api/errors/67bc5fcd969a51aa. Report an issue: GitHub.

Appendix: source

Thrown at spring-beans/src/main/java/org/springframework/beans/BeanUtils.java:217

					if (args[i] == null) {
						Class<?> parameterType = parameterTypes[i];
						argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
					}
					else {
						argsWithDefaultValues[i] = args[i];
					}
				}
				return ctor.newInstance(argsWithDefaultValues);
			}
		}
		catch (InstantiationException ex) {
			throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
		}
		catch (IllegalAccessException ex) {
			throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
		}
		catch (IllegalArgumentException ex) {
			throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
		}
		catch (InvocationTargetException ex) {
			throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
		}
	}

	/**
	 * Return a resolvable constructor for the provided class, either a primary or single
	 * public constructor with arguments, a single non-public constructor with arguments
	 * or simply a default constructor.
	 * <p>Callers have to be prepared to resolve arguments for the returned constructor's
	 * parameters, if any.
	 * @param clazz the class to check
	 * @throws IllegalStateException in case of no unique constructor found at all
	 * @since 5.3
	 * @see #findPrimaryConstructor
	 */
	@SuppressWarnings("unchecked")

View on GitHub (pinned to 69bf83ad71)