spring-projects/spring-framework · error · UnknownAdviceTypeException

Advice object [{}] is neither a supported subinterface of [o

Error message

Advice object [{}] is neither a supported subinterface of [org.aopalliance.aop.Advice] nor an [org.springframework.aop.Advisor]

What it means

Thrown as UnknownAdviceTypeException by DefaultAdvisorAdapterRegistry.wrap when the object passed in is neither an Advisor nor an Advice (the first 'instanceof Advice' check at line 64 fails). The registry only knows how to wrap Advice subinterfaces and existing Advisors; anything else is rejected with this exact message.

Source

Thrown at spring-aop/src/main/java/org/springframework/aop/framework/adapter/DefaultAdvisorAdapterRegistry.java:65


	/**
	 * Create a new DefaultAdvisorAdapterRegistry, registering well-known adapters.
	 */
	public DefaultAdvisorAdapterRegistry() {
		registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
		registerAdvisorAdapter(new AfterReturningAdviceAdapter());
		registerAdvisorAdapter(new ThrowsAdviceAdapter());
	}


	@Override
	public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
		if (adviceObject instanceof Advisor advisor) {
			return advisor;
		}
		if (!(adviceObject instanceof Advice advice)) {
			throw new UnknownAdviceTypeException(adviceObject);
		}
		if (advice instanceof MethodInterceptor) {
			// So well-known it doesn't even need an adapter.
			return new DefaultPointcutAdvisor(advice);
		}
		for (AdvisorAdapter adapter : this.adapters) {
			// Check that it is supported.
			if (adapter.supportsAdvice(advice)) {
				return new DefaultPointcutAdvisor(advice);
			}
		}
		throw new UnknownAdviceTypeException(advice);
	}

	@Override
	public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
		List<MethodInterceptor> interceptors = new ArrayList<>(3);
		Advice advice = advisor.getAdvice();

View on GitHub (pinned to 69bf83ad71)

Solutions

  1. Pass only Advice or Advisor instances to wrap()/addAdvice()/addAdvisor().
  2. If you intended to set the target, use setTarget/setTargetSource instead.
  3. If the bean should be advice, make its class implement MethodBeforeAdvice/AfterReturningAdvice/ThrowsAdvice/MethodInterceptor.

Example fix

// before
proxyFactory.addAdvice(myPlainServiceBean); // not an Advice

// after
proxyFactory.setTarget(myPlainServiceBean);
proxyFactory.addAdvice(new MyMethodInterceptor()); // implements MethodInterceptor
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(obj instanceof Advice) && !(obj instanceof Advisor)) {
  throw new IllegalArgumentException(obj + " is not Advice or Advisor");
}
advisorRegistry.wrap(obj);

Type guard

static boolean isAdviceOrAdvisor(Object o) {
  return o instanceof Advice || o instanceof Advisor;
}

Try / catch

try { Advisor a = registry.wrap(obj); }
catch (UnknownAdviceTypeException e) {
  if (e.getMessage().startsWith("Advice object [")) { /* pass real Advice/Advisor */ }
  throw e;
}

Prevention

When it happens

Trigger: Calling advisorAdapterRegistry.wrap(someObject) or ProxyFactory.addAdvice(someObject) / addAdvisor via a value that is a plain POJO. Also reached indirectly through ProxyFactoryBean when an interceptorNames entry resolves to a non-Advice bean (which is then surfaced as error 90).

Common situations: Passing the target bean (or a String, configuration object) into addAdvice by mistake; mis-typed interceptor beans; refactoring that changed a class to no longer implement an Advice interface.

Related errors


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