spring-projects/spring-framework · error · AopConfigException
Cannot add advisor: Configuration is frozen.
Error message
Cannot add advisor: Configuration is frozen.
What it means
Thrown by AdvisedSupport.addAdvisors(Collection) when the configuration is frozen (isFrozen()==true). This mirrors the remove-side freeze guard: once frozen, the advisor list is immutable and batch additions are rejected up front before any element is processed. Note this check happens before the empty-collection short-circuit, so even adding zero advisors to a frozen config throws.
Source
Thrown at spring-aop/src/main/java/org/springframework/aop/framework/AdvisedSupport.java:381
addAdvisor(index, b);
return true;
}
/**
* Add all the given advisors to this proxy configuration.
* @param advisors the advisors to register
*/
public void addAdvisors(Advisor... advisors) {
addAdvisors(Arrays.asList(advisors));
}
/**
* Add all the given advisors to this proxy configuration.
* @param advisors the advisors to register
*/
public void addAdvisors(Collection<Advisor> advisors) {
if (isFrozen()) {
throw new AopConfigException("Cannot add advisor: Configuration is frozen.");
}
if (!CollectionUtils.isEmpty(advisors)) {
for (Advisor advisor : advisors) {
if (advisor instanceof IntroductionAdvisor introductionAdvisor) {
validateIntroductionAdvisor(introductionAdvisor);
}
Assert.notNull(advisor, "Advisor must not be null");
this.advisors.add(advisor);
}
adviceChanged();
}
}
private void validateIntroductionAdvisor(IntroductionAdvisor advisor) {
advisor.validateInterfaces();
// If the advisor passed validation, we can make the change.
for (Class<?> ifc : advisor.getInterfaces()) {
addInterface(ifc);View on GitHub (pinned to e8729d0438)
Solutions
- Leave setFrozen(false) (default) if the proxy must accept new advisors at runtime.
- Create a new ProxyFactory with the combined advisor set and build a fresh proxy.
- If batch addition is conditional, guard with !advised.isFrozen() before calling addAdvisors to avoid the exception entirely.
Example fix
// before ProxyFactory pf = new ProxyFactory(target); pf.setFrozen(true); Object proxy = pf.getProxy(); ((Advised) proxy).addAdvisors(Arrays.asList(extraAdvisor)); // throws // after ProxyFactory pf = new ProxyFactory(target); // keep frozen=false Object proxy = pf.getProxy(); ((Advised) proxy).addAdvisors(Arrays.asList(extraAdvisor)); // ok
Defensive patterns
Strategy: validation
Validate before calling
Advised advised = (Advised) proxy;
if (advised.isFrozen()) {
// fall back to building a new proxy instead of mutating
ProxyFactory pf = new ProxyFactory();
pf.copyFrom((ProxyConfig) advised);
for (Advisor a : advised.getAdvisors()) pf.addAdvisor(a);
pf.addAdvisors(newAdvisors);
return pf.getProxy();
}
advised.addAdvisors(newAdvisors); Prevention
- Keep frozen=false (default) on proxies that need runtime advisor additions.
- Batch all advisors before getProxy() so runtime mutation isn't required.
- Guard bulk-add code with !isFrozen() and a rebuild fallback.
When it happens
Trigger: Calling advised.addAdvisors(list) on a proxy whose config was frozen; bulk-loading advisors from external config at runtime into a frozen proxy; framework code path that froze the config (e.g. after getProxy with frozen=true) followed by user code calling addAdvisors.
Common situations: Building proxies with frozen=true for performance and later trying to extend them; AOT/native scenarios; shared/prototype configuration snapshots that are intentionally immutable.
Related errors
- Cannot remove Advisor: Configuration is frozen.
- MethodInvocation is not a Spring ProxyMethodInvocation: {}
- 'argumentNames' property of AbstractAspectJAdvice contains a
- Only afterReturning advice can be used to bind a return valu
- Only afterThrowing advice can be used to bind a thrown excep
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/e5088d4d46f4a31f.json.
Report an issue: GitHub.