spring-projects/spring-security · error · IllegalStateException
Failed to resolve an unique bean (single or primary) of type
Error message
Failed to resolve an unique bean (single or primary) of type [{object.getClass()}] from the BeanFactory.
Because the object is a CGLIB Proxy, a raw bean cannot be initialized during runtime in a native image.
What it means
In a GraalVM native image, initializeBeanIfNeeded cannot resolve/initialize a raw bean for a CGLIB proxy object; when the BeanFactory lookup returns null it throws IllegalStateException with a message naming the unresolved type. Native images forbid creating/initializing raw beans at runtime for proxied types because the necessary reflective metadata is absent.
Solutions
- Avoid passing CGLIB-proxied objects through ObjectPostProcessor in native images; post-process the underlying instance or disable proxying where possible.
- Register native/AOT hints (RuntimeHints) for the affected classes so bean resolution works in the image.
- Ensure exactly one primary/single bean of the required type exists, or qualify the bean explicitly.
- Prefer JDK dynamic proxies (proxyTargetClass=false) or restructure config so the object is not proxied before initialization.
Example fix
// before http.objectPostProcessor.postProcess(proxiedConfigurer); // fails in native image // after http.objectPostProcessor.postProcess(new MyConfigurer()); // raw instance, no CGLIB proxy
Defensive patterns
Strategy: try-catch
Validate before calling
// before post-processing in native image
if (SpringFactoriesUtils // or AOT check
.isNativeImage() && AopUtils.isCglibProxy(object)) {
throw new IllegalStateException("Cannot postProcess CGLIB proxy " + object.getClass() + " in native image");
} Type guard
static boolean isCglibProxy(Object o) {
return o != null && org.springframework.aop.support.AopUtils.isCglibProxy(o);
} Try / catch
try {
processed = objectPostProcessor.postProcess(object);
} catch (IllegalStateException e) {
if (e.getMessage().contains("CGLIB Proxy")) {
// rebuild with the raw (unproxied) instance or register native hints
processed = objectPostProcessor.postProcess(AopProxyUtils.getSingletonTarget(object));
} else {
throw e;
}
} Prevention
- Do not pass @Configuration/@Transactional-proxied objects into security post-processors in native builds
- Register RuntimeHints for custom configurer classes
- Ensure a unique primary bean exists for post-processed types
- Test with native-image (AOT) builds in CI, not just JVM runs
When it happens
Trigger: Running a Spring Security configuration in a native image where an object passed to postProcess is a CGLIB proxy (e.g. @Configuration- or @Transactional-proxied classes) and initializeBeanIfNeeded does a getBean of that type which fails to find a unique single/primary bean.
Common situations: Spring Boot native (AOT) builds with security configurers post-processing proxied beans; multiple beans of the same type so no unique candidate resolves; missing native hints for custom configurer classes.
Understand the failure class
Background: "unsupported platform" / "not supported on this platform" errors: what they mean and how to fix them — this error's family across 47 libraries.
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/8581935dc26ea622.
Report an issue: GitHub.
Appendix: source
Thrown at config/src/main/java/org/springframework/security/config/annotation/configuration/AutowireBeanFactoryObjectPostProcessor.java:108
* the application is a native image
* @see <a href=
* "https://github.com/spring-projects/spring-security/issues/14825">Issue
* gh-14825</a>
*/
@SuppressWarnings("unchecked")
private <T> T initializeBeanIfNeeded(T object) {
if (!NativeDetector.inNativeImage() || !AopUtils.isCglibProxy(object)) {
return (T) this.autowireBeanFactory.initializeBean(object, object.toString());
}
ObjectProvider<?> provider = this.autowireBeanFactory.getBeanProvider(object.getClass());
Object bean = provider.getIfUnique();
if (bean == null) {
String msg = """
Failed to resolve an unique bean (single or primary) of type [%s] from the BeanFactory.
Because the object is a CGLIB Proxy, a raw bean cannot be initialized during runtime in a native image.
"""
.formatted(object.getClass());
throw new IllegalStateException(msg);
}
return (T) bean;
}
@Override
public void afterSingletonsInstantiated() {
for (SmartInitializingSingleton singleton : this.smartSingletons) {
singleton.afterSingletonsInstantiated();
}
}
@Override
public void destroy() {
for (DisposableBean disposable : this.disposableBeans) {
try {
disposable.destroy();
}
catch (Exception ex) {View on GitHub (pinned to 96852e8860)