spring-projects/spring-framework · error · IllegalArgumentException

targetField is required

Error message

targetField is required

What it means

Thrown by FieldRetrievingFactoryBean.afterPropertiesSet() when a targetClass or targetObject has been set but the name of the field to read (targetField) was not. FieldRetrievingFactoryBean is a FactoryBean that exposes a Java field as a bean; once you point it at a class or instance, it cannot proceed without knowing which field to retrieve via Class.getField. Spring uses this guard at initialization time to fail fast rather than NPE'ing later during reflection.

Solutions

  1. Add the missing <property name="targetField" value="FIELD_NAME"/> alongside targetClass, or call setTargetField("FIELD_NAME") in code.
  2. Prefer the concise staticField form: <property name="staticField" value="pkg.MyClass.MY_CONST"/> (or set the bean id to that fully-qualified string and set nothing else).
  3. For instance fields, set targetObject (a bean ref or inner bean) AND targetField together; for static fields, set targetClass AND targetField, but never both targetClass and targetObject.

Example fix

// before (broken)
FieldRetrievingFactoryBean fb = new FieldRetrievingFactoryBean();
fb.setTargetClass(java.sql.Connection.class);
// after
FieldRetrievingFactoryBean fb = new FieldRetrievingFactoryBean();
fb.setTargetClass(java.sql.Connection.class);
fb.setTargetField("TRANSACTION_SERIALIZABLE");
// or simply:
// fb.setStaticField("java.sql.Connection.TRANSACTION_SERIALIZABLE");
Defensive patterns

Strategy: validation

Validate before calling

FieldRetrievingFactoryBean fb = new FieldRetrievingFactoryBean();
fb.setTargetClass(MyType.class);
if (fb.getTargetField() == null || fb.getTargetField().isBlank()) {
    throw new IllegalStateException("targetField must be set when targetClass/targetObject is set");
}
fb.afterPropertiesSet();

Type guard

static boolean hasFieldTarget(FieldRetrievingFactoryBean fb) {
    return (fb.getTargetClass() != null || fb.getTargetObject() != null)
        && fb.getTargetField() != null && !fb.getTargetField().isBlank();
}

Try / catch

try {
    fb.afterPropertiesSet();
} catch (IllegalArgumentException ex) {
    if (ex.getMessage().contains("targetField is required")) {
        // log config error, set a default field, or fail fast
    }
    throw ex;
}

Prevention

When it happens

Trigger: Calling setTargetClass(...) or setTargetObject(...) on a FieldRetrievingFactoryBean (or the equivalent XML <property name="targetClass"/>) without a matching <property name="targetField"/>. Equivalently, using <util:constant> style but only supplying targetClass. Note: if you supply staticField (the fully-qualified 'pkg.Class.FIELD' form) instead, targetField is parsed for you and this error is not hit.

Common situations: XML config that sets targetClass to a class but omits targetField (typo or copy-paste missing the field property). Java @Bean config that calls bean.setTargetClass(MyType.class) but forgets bean.setTargetField("MY_CONST"). Migrating from the convenience staticField / bean-name shorthand to the explicit targetClass/targetField form and missing one property.

Related errors


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

Appendix: source

Thrown at spring-beans/src/main/java/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.java:194

				Assert.state(this.staticField != null, "No target field specified");
			}

			// Try to parse static field into class and field.
			int lastDotIndex = this.staticField.lastIndexOf('.');
			if (lastDotIndex == -1 || lastDotIndex == this.staticField.length()) {
				throw new IllegalArgumentException(
						"staticField must be a fully qualified class plus static field name: " +
						"for example, 'example.MyExampleClass.MY_EXAMPLE_FIELD'");
			}
			String className = this.staticField.substring(0, lastDotIndex);
			String fieldName = this.staticField.substring(lastDotIndex + 1);
			this.targetClass = ClassUtils.forName(className, this.beanClassLoader);
			this.targetField = fieldName;
		}

		else if (this.targetField == null) {
			// Either targetClass or targetObject specified.
			throw new IllegalArgumentException("targetField is required");
		}

		// Try to get the exact method first.
		Class<?> targetClass = (this.targetObject != null ? this.targetObject.getClass() : this.targetClass);
		this.fieldObject = targetClass.getField(this.targetField);
	}


	@Override
	public @Nullable Object getObject() throws IllegalAccessException {
		if (this.fieldObject == null) {
			throw new FactoryBeanNotInitializedException();
		}
		ReflectionUtils.makeAccessible(this.fieldObject);
		if (this.targetObject != null) {
			// instance field
			return this.fieldObject.get(this.targetObject);
		}

View on GitHub (pinned to 69bf83ad71)