spring-projects/spring-security · error · IllegalStateException

Could not locate field 'X' on class Y

Error message

Could not locate field 'X' on class Y

What it means

FieldUtils.getField walks the class hierarchy (superclasses) looking for a declared field by name; if neither the class nor any superclass declares it, it throws IllegalStateException('Could not locate field X on class Y'). This utility is intended for testing/reflection use, so the exception signals the assumed field genuinely does not exist on the type (or its name was mistyped).

Source

Thrown at core/src/main/java/org/springframework/security/util/FieldUtils.java:55

	/**
	 * Attempts to locate the specified field on the class.
	 * @param clazz the class definition containing the field
	 * @param fieldName the name of the field to locate
	 * @return the Field (never null)
	 * @throws IllegalStateException if field could not be found
	 */
	public static Field getField(Class<?> clazz, String fieldName) throws IllegalStateException {
		Assert.notNull(clazz, "Class required");
		Assert.hasText(fieldName, "Field name required");
		try {
			return clazz.getDeclaredField(fieldName);
		}
		catch (NoSuchFieldException ex) {
			// Try superclass
			if (clazz.getSuperclass() != null) {
				return getField(clazz.getSuperclass(), fieldName);
			}
			throw new IllegalStateException("Could not locate field '" + fieldName + "' on class " + clazz);
		}
	}

	/**
	 * Returns the value of a (nested) field on a bean. Intended for testing.
	 * @param bean the object
	 * @param fieldName the field name, with "." separating nested properties
	 * @return the value of the nested field
	 */
	public static Object getFieldValue(Object bean, String fieldName) throws IllegalAccessException {
		Assert.notNull(bean, "Bean cannot be null");
		Assert.hasText(fieldName, "Field name required");
		String[] nestedFields = StringUtils.tokenizeToStringArray(fieldName, ".");
		Class<?> componentClass = bean.getClass();
		Object value = bean;
		for (String nestedField : nestedFields) {
			Field field = getField(componentClass, nestedField);
			field.setAccessible(true);

View on GitHub (pinned to 96852e8860)

Solutions

  1. Correct the field name and verify the declaring class with clazz.getDeclaredFields() before the call
  2. Call getField against the actual declaring class rather than a subclass/interface
  3. Use standard reflection with setAccessible(true) or the Spring ReflectionUtils if you need interface-declared or more flexible lookup
  4. Replace reflection with a getter/public API where available to remove fragility

Example fix

// before
Object v = FieldUtils.getField(bean, "usrName"); // typo -> IllegalStateException
// after
Object v = FieldUtils.getField(bean, "userName");
Defensive patterns

Strategy: try-catch

Validate before calling

boolean declared = false;
for (Class<?> c = bean.getClass(); c != null; c = c.getSuperclass()) {
    try { c.getDeclaredField("userName"); declared = true; break; }
    catch (NoSuchFieldException ignored) { }
}
if (!declared) throw new IllegalStateException("Field 'userName' not found");

Type guard

static boolean hasField(Class<?> clazz, String name) {
    for (Class<?> c = clazz; c != null; c = c.getSuperclass()) {
        try { c.getDeclaredField(name); return true; }
        catch (NoSuchFieldException ignored) { }
    }
    return false;
}

Try / catch

try {
    Object value = FieldUtils.getField(bean, "userName");
} catch (IllegalStateException e) {
    if (e.getMessage().startsWith("Could not locate field")) {
        // fall back to getter or fail the test with a clear message
    } else { throw e; }
}

Prevention

When it happens

Trigger: Calling FieldUtils.getField(bean, "fieldName") where the target class (and all superclasses) lack that field; typos or renamed/refactored fields not updated at the reflection call site; accessing a nested field via dotted path where an intermediate segment's type does not declare the next field; library upgrade changed an internal field name.

Common situations: Test helpers asserting on private/internal state after refactoring; accessing framework internals (e.g., inside Spring Security filters) that changed between versions; reflection on fields that are inherited through interfaces rather than classes (which the superclass walk does not cover).

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/6ffa91a6c342740f. Report an issue: GitHub.