spring-projects/spring-framework · error · UnsupportedOperationException
Only afterThrowing advice can be used to bind a thrown excep
Error message
Only afterThrowing advice can be used to bind a thrown exception
What it means
The base AbstractAspectJAdvice.setThrowingName(String) (line 325-327) is a guard that throws UnsupportedOperationException: only after-throwing advice can bind a thrown exception. AspectJAfterThrowingAdvice overrides this method; any other advice subtype retains the throwing base implementation and rejects the call.
Source
Thrown at spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java:326
}
catch (Throwable ex) {
throw new IllegalArgumentException("Returning name '" + name +
"' is neither a valid argument name nor the fully-qualified " +
"name of a Java type on the classpath. Root cause: " + ex);
}
}
}
protected Class<?> getDiscoveredReturningType() {
return this.discoveredReturningType;
}
protected @Nullable Type getDiscoveredReturningGenericType() {
return this.discoveredReturningGenericType;
}
public void setThrowingName(String name) {
throw new UnsupportedOperationException("Only afterThrowing advice can be used to bind a thrown exception");
}
/**
* We need to hold the throwing name at this level for argument binding calculations,
* this method allows the afterThrowing advice subclass to set the name.
*/
protected void setThrowingNameNoCheck(String name) {
// name could be a variable or a type...
if (isVariableName(name)) {
this.throwingName = name;
}
else {
// assume a type
try {
this.discoveredThrowingType = ClassUtils.forName(name, getAspectClassLoader());
}
catch (Throwable ex) {
throw new IllegalArgumentException("Throwing name '" + name +View on GitHub (pinned to e8729d0438)
Solutions
- Place the 'throwing' attribute only on an <aop:after-throwing> element (or @AfterThrowing advice).
- Remove 'throwing' from the before/after/after-returning/around element causing the error.
- For around advice, capture exceptions via try/catch around pjp.proceed() instead of a throwing binding.
- When building advice programmatically, call setThrowingName only on AspectJAfterThrowingAdvice.
Example fix
// before
@Around(value = "execution(* svc.*(..))", throwing = "ex")
public Object around(ProceedingJoinPoint pjp, Exception ex) { ... }
// after
@AfterThrowing(value = "execution(* svc.*(..))", throwing = "ex")
public void onThrow(Exception ex) { ... } Defensive patterns
Strategy: validation
Validate before calling
// Only call setThrowingName on the correct advice subtype.
if (advice instanceof AspectJAfterThrowingAdvice) {
advice.setThrowingName(name);
} else {
throw new IllegalStateException("throwing binding requires after-throwing advice, got " + advice.getClass());
} Type guard
private static boolean supportsThrowing(AbstractAspectJAdvice a) {
return a instanceof AspectJAfterThrowingAdvice;
} Try / catch
try {
advice.setThrowingName(name);
} catch (UnsupportedOperationException ex) {
throw new IllegalStateException(
"'throwing' is only valid on after-throwing advice; remove it from " + advice.getClass().getSimpleName(), ex);
} Prevention
- Place 'throwing' only on after-throwing advice (XML element or @AfterThrowing).
- For around advice, catch exceptions via proceed() instead of a throwing binding.
- When templating advice XML, change advice kind and strip returning/throwing together.
When it happens
Trigger: Calling setThrowingName (or configuring a 'throwing' attribute) on AspectJMethodBeforeAdvice, AspectJAfterAdvice, AspectJAfterReturningAdvice, or AspectJAroundAdvice, i.e. putting throwing="..." on <aop:before>, <aop:after>, <aop:after-returning>, or <aop:around>.
Common situations: XML/annotation misconfiguration: reusing an after-throwing block as a template and leaving 'throwing' on the now-different advice kind; expecting exception binding on around advice (around should catch via proceed() instead).
Related errors
- Only afterReturning advice can be used to bind a return valu
- Throwing argument name '{}' was not bound in advice argument
- Binding of throwing parameter '{}' could not be completed as
- MethodInvocation is not a Spring ProxyMethodInvocation: {}
- 'argumentNames' property of AbstractAspectJAdvice contains a
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/7ace6b6180ba2a12.json.
Report an issue: GitHub.