spring-projects/spring-framework · error · IllegalStateException

Cannot create scoped proxy for bean

Error message

Cannot create scoped proxy for bean '{targetBeanName}': Target type could not be determined at the time of proxy creation.

What it means

Thrown by ScopedProxyFactoryBean.setBeanFactory (line 97-101) when beanFactory.getType(targetBeanName) returns null, meaning the factory cannot determine the target bean's type at proxy-creation time. The proxy needs a concrete interface or class set to generate the proxy, so an unknown type is rejected with an IllegalStateException.

Solutions

  1. Ensure the target bean is registered and its type is determinable before the scoped proxy is created (have FactoryBean.getObjectType return a non-null class early).
  2. Break circular dependencies so the target bean type can be resolved without needing the proxy.
  3. Verify setTargetBeanName(...) is called with the correct bean name.
  4. If using a FactoryBean, make getObjectType() return a stable type even before afterPropertiesSet.

Example fix

// before
public class ClientFactoryBean implements FactoryBean<Client> {
    public Class<?> getObjectType() { return null; } // unknown early
}

// after
public class ClientFactoryBean implements FactoryBean<Client> {
    public Class<?> getObjectType() { return Client.class; } // resolvable
}
Defensive patterns

Strategy: validation

Validate before calling

if (beanFactory.getType(targetBeanName) == null) {
    throw new IllegalStateException(
        "Cannot resolve type of '" + targetBeanName + "' before creating scoped proxy");
}

Prevention

When it happens

Trigger: Creating a scoped proxy whose target bean's type is not determinable: the target is a FactoryBean whose getObjectType() returns null (e.g. based on a not-yet-built resource), the target bean does not exist yet at the time the proxy is created, or a circular early reference prevents type resolution. Also when targetBeanName was never set or points to a non-existent bean.

Common situations: A scoped FactoryBean whose object type is only known after initialization (e.g. JPA/Kafka/dynamic client FactoryBeans). Circular dependency where the scoped target references the proxy. Forgetting to call setTargetBeanName. Beans defined with lazy or programmatic registration that are not yet resolvable.

Related errors


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

Appendix: source

Thrown at spring-aop/src/main/java/org/springframework/aop/scope/ScopedProxyFactoryBean.java:99

		this.targetBeanName = targetBeanName;
		this.scopedTargetSource.setTargetBeanName(targetBeanName);
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) {
		if (!(beanFactory instanceof ConfigurableBeanFactory cbf)) {
			throw new IllegalStateException("Not running in a ConfigurableBeanFactory: " + beanFactory);
		}
		this.scopedTargetSource.setBeanFactory(beanFactory);

		ProxyFactory pf = new ProxyFactory();
		pf.copyFrom(this);
		pf.setTargetSource(this.scopedTargetSource);

		Assert.notNull(this.targetBeanName, "Property 'targetBeanName' is required");
		Class<?> beanType = beanFactory.getType(this.targetBeanName);
		if (beanType == null) {
			throw new IllegalStateException("Cannot create scoped proxy for bean '" + this.targetBeanName +
					"': Target type could not be determined at the time of proxy creation.");
		}
		if (!isProxyTargetClass() || beanType.isInterface() || Modifier.isPrivate(beanType.getModifiers())) {
			pf.setInterfaces(ClassUtils.getAllInterfacesForClass(beanType, cbf.getBeanClassLoader()));
		}

		// Add an introduction that implements only the methods on ScopedObject.
		ScopedObject scopedObject = new DefaultScopedObject(cbf, this.scopedTargetSource.getTargetBeanName());
		pf.addAdvice(new DelegatingIntroductionInterceptor(scopedObject));

		// Add the AopInfrastructureBean marker to indicate that the scoped proxy
		// itself is not subject to auto-proxying! Only its target bean is.
		pf.addInterface(AopInfrastructureBean.class);

		this.proxy = pf.getProxy(cbf.getBeanClassLoader());
	}

View on GitHub (pinned to 69bf83ad71)