spring-projects/spring-framework · error · FatalBeanException

Could not copy property '{targetPd.getName()}' from source t

Error message

Could not copy property '{targetPd.getName()}' from source to target

What it means

Thrown as a FatalBeanException from the copyProperties loop when invoking either the source's read method or the target's write method throws anything (Throwable). Spring wraps the underlying reflection failure (e.g. IllegalAccessException, InvocationTargetException wrapping an NPE, type incompatibility) and names the property that failed.

Source

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

				CachedIntrospectionResults.forClass(source.getClass()) : null);

		for (PropertyDescriptor targetPd : targetPds) {
			Method writeMethod = targetPd.getWriteMethod();
			if (writeMethod != null && (ignoredProps == null || !ignoredProps.contains(targetPd.getName()))) {
				PropertyDescriptor sourcePd = (sourceResults != null ?
						sourceResults.getPropertyDescriptor(targetPd.getName()) : targetPd);
				if (sourcePd != null) {
					Method readMethod = sourcePd.getReadMethod();
					if (readMethod != null) {
						if (isAssignable(writeMethod, readMethod, sourcePd, targetPd)) {
							try {
								ReflectionUtils.makeAccessible(readMethod);
								Object value = readMethod.invoke(source);
								ReflectionUtils.makeAccessible(writeMethod);
								writeMethod.invoke(target, value);
							}
							catch (Throwable ex) {
								throw new FatalBeanException(
										"Could not copy property '" + targetPd.getName() + "' from source to target", ex);
							}
						}
					}
				}
			}
		}
	}

	private static boolean isAssignable(Method writeMethod, Method readMethod,
			PropertyDescriptor sourcePd, PropertyDescriptor targetPd) {

		Type paramType = writeMethod.getGenericParameterTypes()[0];
		if (paramType instanceof Class<?> clazz) {
			return ClassUtils.isAssignable(clazz, readMethod.getReturnType());
		}
		else if (paramType.equals(readMethod.getGenericReturnType())) {
			return true;

View on GitHub (pinned to 69bf83ad71)

Solutions

  1. Read the wrapped cause (getCause()/getRootCause()) of the FatalBeanException; the named property tells you which bean property failed.
  2. Fix the setter/read-method logic so it no longer throws (null-checks, validation, default values).
  3. Skip the offending property using the ignoreProperties varargs of copyProperties, or exclude it explicitly.
  4. If the failure is an access restriction, ensure the methods are accessible (public getters/setters, open module via --add-opens).

Example fix

// before
BeanUtils.copyProperties(src, target);
// setter 'setFoo' throws on null

// after - ignore the problematic property
BeanUtils.copyProperties(src, target, "foo");
// or fix the setter to tolerate null
Defensive patterns

Strategy: try-catch

Try / catch

try {
    BeanUtils.copyProperties(src, target);
} catch (FatalBeanException ex) {
    // ex.getMessage() names the property that failed
    Throwable cause = ex.getCause(); // the real reflective failure
    log.warn("copy failed for property: {}", ex.getMessage(), cause);
}

Prevention

When it happens

Trigger: Inside BeanUtils.copyProperties, after isAssignable passes, the code calls readMethod.invoke(source) then writeMethod.invoke(target, value); if either throws, the catch(Throwable) wraps it in FatalBeanException with the offending targetPd.getName().

Common situations: A setter on the target throws an exception (validation, NPE on a converted null, unsupported value), the read method accesses a field that is lazily initialized and fails, a method became inaccessible under a strict module/SecurityManager setup, or value conversion between incompatible types at the reflective invoke level.

Related errors


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