spring-projects/spring-framework · error · UnsatisfiedDependencyException
Unsatisfied dependency expressed through injection point
Error message
Unsatisfied dependency expressed through injection point
What it means
Thrown as an UnsatisfiedDependencyException when the AOT BeanInstanceSupplier cannot resolve an autowired argument of the bean's constructor or factory method. In resolveAutowiredArgument, the supplier delegates to RegisteredBean.resolveAutowiredArgument; if that throws a BeansException (no candidate, ambiguous, conversion failure), it is wrapped with the bean name and the DependencyDescriptor so the failing injection point is visible.
Source
Thrown at spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanInstanceSupplier.java:341
ValueHolder resolvedHolder = new ValueHolder(value, valueHolder.getType(), valueHolder.getName());
resolvedHolder.setSource(valueHolder);
return resolvedHolder;
}
private @Nullable Object resolveAutowiredArgument(RegisteredBean registeredBean, DependencyDescriptor descriptor,
@Nullable ValueHolder argumentValue, Set<String> autowiredBeanNames) {
TypeConverter typeConverter = registeredBean.getBeanFactory().getTypeConverter();
if (argumentValue != null) {
return (argumentValue.isConverted() ? argumentValue.getConvertedValue() :
typeConverter.convertIfNecessary(argumentValue.getValue(),
descriptor.getDependencyType(), descriptor.getMethodParameter()));
}
try {
return registeredBean.resolveAutowiredArgument(descriptor, typeConverter, autowiredBeanNames);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, registeredBean.getBeanName(), descriptor, ex);
}
}
private Object instantiate(RegisteredBean registeredBean, Executable executable, @Nullable Object[] args) {
if (executable instanceof Constructor<?> constructor) {
if (registeredBean.getBeanFactory() instanceof DefaultListableBeanFactory dlbf &&
registeredBean.getMergedBeanDefinition().hasMethodOverrides()) {
return dlbf.getInstantiationStrategy().instantiate(registeredBean.getMergedBeanDefinition(),
registeredBean.getBeanName(), registeredBean.getBeanFactory());
}
return BeanUtils.instantiateClass(constructor, args);
}
if (executable instanceof Method method) {
Object target = null;
String factoryBeanName = registeredBean.getMergedBeanDefinition().getFactoryBeanName();
if (factoryBeanName != null) {
target = registeredBean.getBeanFactory().getBean(factoryBeanName, method.getDeclaringClass());
}View on GitHub (pinned to 69bf83ad71)
Solutions
- Look at the DependencyDescriptor in the exception to find the constructor/factory-method parameter that failed, then register or qualify a bean of that type.
- Add @Qualifier or @Primary to disambiguate when multiple candidates of the parameter type exist.
- Verify @Value placeholders resolve and that a PropertySourcesPlaceholderConfigurer/Environment is present in the native image.
- If the parameter is optional, make it Optional<T>, ObjectProvider<T>, or mark @Autowired(required=false) as appropriate for the injection point.
- Regenerate AOT artifacts (clean native build) after changing the bean class to avoid stale metadata.
Example fix
// before: constructor needs a missing collaborator -> UnsatisfiedDependencyException
public OrderService(PaymentGateway gateway) { ... }
// after: register the bean and disambiguate
@Bean
@Primary
public PaymentGateway stripeGateway() { ... } Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check that constructor/factory-method arguments are resolvable
for (Class<?> pt : executable.getParameterTypes()) {
if (bf.getBeanNamesForType(pt).length == 0 && !isOptional(pt)) {
throw new IllegalStateException("Missing bean for constructor arg: " + pt);
}
} Try / catch
try {
return instanceSupplier.get(registeredBean);
} catch (UnsatisfiedDependencyException ex) {
throw new ConfigurationException("Cannot instantiate " + registeredBean.getBeanName(), ex);
} Prevention
- Use constructor injection with mandatory collaborators so missing beans fail at startup.
- Add @Primary or @Qualifier to disambiguate ambiguous constructor parameters.
- Write an integration test that loads the context in AOT mode.
- Keep AOT metadata in sync with bean class signatures.
When it happens
Trigger: Invoking a generated BeanInstanceSupplier whose underlying constructor/factory method has arguments that beanFactory.resolveDependency cannot satisfy at runtime. Common when an autowired constructor parameter has no qualifying bean, multiple candidates without @Primary/@Qualifier, or an unconvertible value.
Common situations: Bean instantiated by AOT supplier whose constructor needs a collaborator that was not registered in the trimmed native-image context; constructor-injected @Value with an unresolved placeholder; multiple DataSource/RestTemplate-style beans with no disambiguation; bean class changed signature in a new version but the AOT metadata is stale.
Related errors
- Unsatisfied dependency expressed through field
- Unsatisfied dependency expressed through parameter
- Failed to load Class [
- Failed to instantiate method
- failed to generate code for bean definition
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/595724f10409ef43.
Report an issue: GitHub.