quarkusio/quarkus · error · IllegalArgumentException
No interceptor bindings
Error message
No interceptor bindings
What it means
resolveInterceptors requires at least one interceptor binding annotation. With zero bindings there is nothing meaningful to match interceptors against, so Arc throws IllegalArgumentException immediately (after the early 'no interceptors registered' fast path). This guards BeanManager.resolveInterceptors(InterceptionType, Annotation...) usage.
Source
Thrown at independent-projects/arc/runtime/src/main/java/io/quarkus/arc/impl/ArcContainerImpl.java:902
for (InjectableObserverMethod<?> observer : observers) {
if (EventTypeAssignabilityRules.instance().matches(observer.getObservedType(), eventTypes)) {
if (observer.getObservedQualifiers().isEmpty()
|| registeredQualifiers.isSubset(observer.getObservedQualifiers(), eventQualifiers)) {
resolvedObservers.add((InjectableObserverMethod<? super T>) observer);
}
}
}
// Observers with smaller priority values are called first
Collections.sort(resolvedObservers);
return resolvedObservers;
}
List<Interceptor<?>> resolveInterceptors(InterceptionType type, Annotation... interceptorBindings) {
if (interceptors.isEmpty()) {
return Collections.emptyList();
}
if (interceptorBindings.length == 0) {
throw new IllegalArgumentException("No interceptor bindings");
}
registeredInterceptorBindings.verify(interceptorBindings);
List<Interceptor<?>> interceptors = new ArrayList<>();
List<Annotation> bindings = new ArrayList<>();
for (Annotation binding : interceptorBindings) {
bindings.add(binding);
Set<Annotation> transitive = registeredInterceptorBindings.getTransitive(binding.annotationType());
if (transitive != null) {
bindings.addAll(transitive);
}
}
for (InjectableInterceptor<?> interceptor : this.interceptors) {
if (interceptor.intercepts(type) && hasAllInterceptionBindings(interceptor, bindings)) {
interceptors.add(interceptor);
}
}
return interceptors;
}View on GitHub (pinned to e1c734241f)
Solutions
- Pass at least one interceptor binding annotation (e.g. @Transactional.Literal.INSTANCE or a custom binding literal)
- Guard the call: if bindings.length == 0 return an empty list instead of calling resolveInterceptors
- Check the annotations collected reflectively actually include @InterceptorBinding-annotated annotations
Example fix
// before
manager.resolveInterceptors(InterceptionType.AROUND_INVOKE); // empty
// after
manager.resolveInterceptors(InterceptionType.AROUND_INVOKE,
MyBinding.Literal.INSTANCE); Defensive patterns
Strategy: validation
Validate before calling
if (bindings == null || bindings.length == 0) {
throw new IllegalArgumentException("At least one interceptor binding is required");
}
List<Interceptor<?>> its = bm.resolveInterceptors(InterceptionType.AROUND_INVOKE, bindings); Try / catch
try {
return bm.resolveInterceptors(type, bindings);
} catch (IllegalArgumentException e) {
LOGGER.warn("No interceptor bindings supplied");
return List.of();
} Prevention
- Always pass at least one binding annotation literal to resolveInterceptors
- When collecting annotations reflectively, filter for @InterceptorBinding meta-annotated ones and check the result is non-empty
- Write a unit test that exercises the interceptor chain assembly path
When it happens
Trigger: Calling beanManager.resolveInterceptors(InterceptionType.AROUND_INVOKE) or with an empty bindings array; programmatically building an interceptor chain and passing an empty annotation list; a bug in code that filters bindings down to zero.
Common situations: Custom AOP/extension code introspecting interceptors; dynamic proxies built by hand; reflection collecting annotations from a member that actually has none.
Related errors
- Contextual parameter must not be null
- Interface '${declaringClass}' default method '${method}' has
- Not an annotation:
- The set of bean types must not be empty
- Type ${beanType} is not a bean type of ${bean}; its bean typ
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/435ba5fc2ed93a18.
Report an issue: GitHub.