spring-projects/spring-framework · error · IllegalStateException

Specified field type [

Error message

Specified field type [

What it means

Thrown by InjectionMetadata.InjectedElement.checkResourceType() when the declared type of an @Autowired/@Resource field is incompatible with the resolved resource type — neither type is assignable to the other in either direction (checked at line 230). This catches type mismatches between what is declared on the injection point and what Spring resolves to inject.

Source

Thrown at spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java:231

		}

		protected final Class<?> getResourceType() {
			if (this.isField) {
				return ((Field) this.member).getType();
			}
			else if (this.pd != null) {
				return this.pd.getPropertyType();
			}
			else {
				return ((Method) this.member).getParameterTypes()[0];
			}
		}

		protected final void checkResourceType(Class<?> resourceType) {
			if (this.isField) {
				Class<?> fieldType = ((Field) this.member).getType();
				if (!(resourceType.isAssignableFrom(fieldType) || fieldType.isAssignableFrom(resourceType))) {
					throw new IllegalStateException("Specified field type [" + fieldType +
							"] is incompatible with resource type [" + resourceType.getName() + "]");
				}
			}
			else {
				Class<?> paramType =
						(this.pd != null ? this.pd.getPropertyType() : ((Method) this.member).getParameterTypes()[0]);
				if (!(resourceType.isAssignableFrom(paramType) || paramType.isAssignableFrom(resourceType))) {
					throw new IllegalStateException("Specified parameter type [" + paramType +
							"] is incompatible with resource type [" + resourceType.getName() + "]");
				}
			}
		}

		/**
		 * Whether the property values should be injected.
		 * @param pvs property values to check
		 * @return whether the property values should be injected
		 * @since 6.0.10

View on GitHub (pinned to 69bf83ad71)

Solutions

  1. Ensure the field type is compatible (assignable) with the actual bean type — either the same type, a supertype, or a subtype.
  2. If injecting by name with @Resource, verify the named bean's class matches or is assignable to the field type.
  3. If the type hierarchy changed, update the injection point to use the correct common interface or type.

Example fix

// before
@Resource(name = "stringCache")
private IntegerCache cache; // stringCache is a StringCache, incompatible

// after
@Resource(name = "stringCache")
private StringCache cache; // types now match
Defensive patterns

Strategy: validation

Validate before calling

// Verify field type compatibility before injection
for (Field f : beanClass.getDeclaredFields()) {
    if (f.isAnnotationPresent(Resource.class)) {
        Resource r = f.getAnnotation(Resource.class);
        if (!r.name().isEmpty() && beanFactory.containsBean(r.name())) {
            Class<?> beanType = beanFactory.getType(r.name());
            if (beanType != null
                    && !f.getType().isAssignableFrom(beanType)
                    && !beanType.isAssignableFrom(f.getType())) {
                throw new IllegalStateException(
                    "Field type " + f.getType() + " incompatible with bean " + r.name());
            }
        }
    }
}

Prevention

When it happens

Trigger: A field annotated for injection declares a type that is neither a supertype nor subtype of the resolved bean type. For example, a field of type Foo is resolved to a bean of type Bar where neither extends the other.

Common situations: Using @Resource(name="...") to inject a bean whose type does not match the field. Changing a bean's implementation class without updating the injection point type. Injecting by name where the named bean's type diverges from the field type. Generic type erasure causing a runtime type mismatch.

Related errors


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