quarkusio/quarkus · error · IllegalStateException
HTTP Security policy applied only on Quarkus REST cannot be
Error message
HTTP Security policy applied only on Quarkus REST cannot be run as 'RoutingContext' is null
What it means
The eager HTTP security path-matching policy (quarkus.http.auth.permission.* policies applied via Quarkus REST's JaxRsPathMatchingPolicy) requires access to the Vert.x RoutingContext. getPermissionCheck unwraps it from the request context; if absent, the check cannot run and IllegalStateException is thrown.
Source
Thrown at extensions/resteasy-reactive/rest/runtime/src/main/java/io/quarkus/resteasy/reactive/server/runtime/security/EagerSecurityContext.java:93
// and write to a volatile variable during the request; the EagerSecurityHandler is created for each
// endpoint (in case there is HTTP permission configured), so there can be a lot of them
instance = this;
}
Uni<SecurityIdentity> getDeferredIdentity() {
return Uni.createFrom().deferred(new Supplier<Uni<? extends SecurityIdentity>>() {
@Override
public Uni<SecurityIdentity> get() {
return identityAssociation.get().getDeferredIdentity();
}
});
}
Uni<SecurityIdentity> getPermissionCheck(ResteasyReactiveRequestContext requestContext, SecurityIdentity identity,
MethodDescription invokedMethodDesc) {
final RoutingContext routingContext = requestContext.unwrap(RoutingContext.class);
if (routingContext == null) {
throw new IllegalStateException(
"HTTP Security policy applied only on Quarkus REST cannot be run as 'RoutingContext' is null");
}
record SecurityCheckWithIdentity(SecurityIdentity identity, HttpSecurityPolicy.CheckResult checkResult) {
}
return jaxRsPathMatchingPolicy
.checkPermission(routingContext, identity == null ? getDeferredIdentity() : Uni.createFrom().item(identity),
invokedMethodDesc)
.flatMap(new Function<HttpSecurityPolicy.CheckResult, Uni<? extends SecurityCheckWithIdentity>>() {
@Override
public Uni<SecurityCheckWithIdentity> apply(HttpSecurityPolicy.CheckResult checkResult) {
if (identity != null) {
return Uni.createFrom().item(new SecurityCheckWithIdentity(identity, checkResult));
}
if (checkResult.isPermitted() && checkResult.getAugmentedIdentity() == null) {
return Uni.createFrom().item(new SecurityCheckWithIdentity(null, checkResult));
}
// we need to resolve identity either to compare augmented identity or to determine
// whether the identity is anonymous (determines thrown exception for denied access)View on GitHub (pinned to e1c734241f)
Solutions
- Ensure the security check only runs within a normal HTTP request handled by Quarkus REST (a RoutingContext is present)
- Do not invoke resource methods secured by HTTP permission policies outside the Vert.x request pipeline (e.g. in unit tests use QuarkusTest with a real HTTP call)
- Reorder custom handlers so the Vert.x unwrap is available when eager security runs
- If you don't need path-based HTTP permissions for this endpoint, scope the quarkus.http.auth.permission paths away from it
Example fix
// test: call over HTTP instead of invoking the method directly
// before
new MyResource().secured();
// after
given().when().get("/secured").then().statusCode(403);
Defensive patterns
Strategy: try-catch
Validate before calling
// before running the check, confirm a RoutingContext is available
RoutingContext rc = requestContext.unwrap(RoutingContext.class);
if (rc == null) {
// skip HTTP-policy check or route the call through a real HTTP request
} Type guard
RoutingContext rc = requestContext.unwrap(RoutingContext.class); boolean hasRoutingContext = rc != null;
Try / catch
try {
return securityContext.getPermissionCheck(requestContext, identity, methodDesc);
} catch (IllegalStateException e) {
if (e.getMessage().contains("RoutingContext")) {
// fall back to a policy not tied to RoutingContext or reject
} else throw e;
} Prevention
- Test secured endpoints over real HTTP calls (QuarkusTest + REST client), not direct method calls
- Don't reuse eager security handlers outside the Vert.x request pipeline
- Scope HTTP permission policies to endpoints actually served over HTTP
When it happens
Trigger: An HTTP permission policy (quarkus.http.auth.permission...) whose policy applies only on Quarkus REST is evaluated for a request whose ResteasyReactiveRequestContext cannot be unwrapped to a RoutingContext — e.g. the security check runs outside a normal Vert.x HTTP request flow.
Common situations: Invoking resource methods through non-HTTP dispatch paths or tests without a Vert.x context; custom security checks reusing EagerSecurityContext outside the standard request pipeline; misordered handlers stripping the context.
Related errors
- Unable to determine if bean '${className}' is available
- Registering default SecurityCheck that requires secured meth
- Security annotation placed on resource method '${className}#
- Failed to find any non-blocking provider for startup actions
- Cannot transform exception ${exception}
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/d1d61f00e8bdadca.
Report an issue: GitHub.