spring-projects/spring-framework · error · IllegalStateException

Specified field type [{}] is incompatible with resource type

Error message

Specified field type [{}] is incompatible with resource type [{}]

What it means

During injection metadata building, InjectionMetadata.InjectedElement.checkResourceType verifies that a @Resource/@Inject target field's declared type is assignment-compatible with the resolved resource type. If neither type is assignable to the other, Spring refuses to inject because the value would not be type-safe. This guards against silent ClassCastException at injection time.

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 e8729d0438)

Solutions

  1. Verify the resolved bean's actual type matches (or is assignable to/from) the field type - check the bean name in @Resource and the registered bean definitions.
  2. If a name collision resolves the wrong bean, qualify explicitly with the correct bean name or mark it @Primary.
  3. Update the field type to the implementation/interface that Spring actually provides, or register the correct type.
  4. Remove the stale bean definition that is shadowing the intended one.

Example fix

// before
@Resource
private DataSource cache; // 'cache' bean is actually a Caffeine Map
// after
@Resource(name = "dataSource")
private DataSource cache;
Defensive patterns

Strategy: type-guard

Validate before calling

Field f = ...; // the @Resource field
Class<?> beanType = context.getType(beanName);
Class<?> fieldType = f.getType();
if (!(fieldType.isAssignableFrom(beanType) || beanType.isAssignableFrom(fieldType))) {
  throw new IllegalStateException(fieldType + " incompatible with " + beanType);
}

Type guard

boolean typesCompatible(Class<?> fieldType, Class<?> resourceType) {
  return fieldType.isAssignableFrom(resourceType) || resourceType.isAssignableFrom(fieldType);
}

Prevention

When it happens

Trigger: A field annotated with @Resource (or processed by CommonAnnotationBeanPostProcessor) whose declared type is incompatible with the resource/bean Spring resolves for that name or type. For example @Resource private DataSource field but the matching bean is a String.

Common situations: Wrong bean name resolved (name collision), a registered bean of an unexpected type shadowing the intended one, a field type that was changed without updating the wiring, or mixing interface/implementation types where neither is assignable to the other (e.g. two unrelated hierarchies).

Related errors


AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04). Data as JSON: /data/errors/aed95be2249245dd.json. Report an issue: GitHub.