{"record":{"id":"080197d293ae7982","repo":"quarkusio/quarkus","slug":"cannot-be-called-from-response-filter","errorCode":null,"errorMessage":"Cannot be called from response filter","messagePattern":"Cannot be called from response filter","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/jaxrs/ContainerRequestContextImpl.java","lineNumber":95,"sourceCode":"    public String getMethod() {\n        return quarkusRestContext.getMethod();\n    }\n\n    @Override\n    public void setMethod(String method) {\n        assertPreMatch();\n        quarkusRestContext.setMethod(method);\n    }\n\n    public void assertPreMatch() {\n        if (!isPreMatch()) {\n            throw new IllegalStateException(\"Can only be called from a @PreMatch filter\");\n        }\n    }\n\n    public void assertNotResponse() {\n        if (isResponse()) {\n            throw new IllegalStateException(\"Cannot be called from response filter\");\n        }\n    }\n\n    @Override\n    public MultivaluedMap<String, String> getHeaders() {\n        return quarkusRestContext.getHttpHeaders().getMutableHeaders();\n    }\n\n    @Override\n    public String getHeaderString(String name) {\n        return quarkusRestContext.getHttpHeaders().getHeaderString(name);\n    }\n\n    @Override\n    public boolean containsHeaderString(String name, String valueSeparatorRegex, Predicate<String> valuePredicate) {\n        return quarkusRestContext.getHttpHeaders().containsHeaderString(name, valueSeparatorRegex, valuePredicate);\n    }\n","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/server/runtime/src/main/java/org/jboss/resteasy/reactive/server/jaxrs/ContainerRequestContextImpl.java#L77-L113","documentation":"ContainerRequestContext methods that mutate request state (setEntityStream, setSecurityContext, abortWith) are forbidden in response filters per JAX-RS. ContainerRequestContextImpl.assertNotResponse throws IllegalStateException if the context is being used as a ContainerResponseContext phase, preventing illegal mutation of an already-processed request.","triggerScenarios":"Calling ctx.abortWith(...), ctx.setEntityStream(...), or ctx.setSecurityContext(...) inside a ContainerResponseFilter, or inside a request filter running in the response phase (e.g. via shared code invoked from both).","commonSituations":"A single filter implementing both ContainerRequestFilter and ContainerResponseFilter sharing mutation code; trying to short-circuit in a response filter instead of the request filter; copy-pasted abortWith logic into the response filter.","solutions":["Move abortWith/setEntityStream/setSecurityContext calls into a ContainerRequestFilter (pre or post match)","In a response filter, mutate the ContainerResponseContext instead (e.g. setEntity, setStatus)","Guard shared code with an instanceof/phase check before mutating request state","Use requestContext.abortWith only before the response chain begins"],"exampleFix":"// before\npublic class MyFilter implements ContainerResponseFilter {\n    public void filter(ContainerRequestContext req, ContainerResponseContext res) {\n        req.abortWith(Response.ok().build()); // fails\n    }\n}\n// after\npublic class MyFilter implements ContainerResponseFilter {\n    public void filter(ContainerRequestContext req, ContainerResponseContext res) {\n        res.setStatus(200);\n    }\n}","handlingStrategy":"validation","validationCode":"if (this instanceof ContainerResponseFilter) {\n    // never call abortWith/setEntityStream/setSecurityContext here\n}","typeGuard":null,"tryCatchPattern":"try { ctx.abortWith(resp); } catch (IllegalStateException e) { if (e.getMessage().contains(\"response filter\")) { responseCtx.setStatus(resp.getStatus()); } else { throw e; } }","preventionTips":["Call abortWith only from request filters","In response filters mutate ContainerResponseContext instead","Avoid sharing mutating code between request and response filter paths"],"tags":["resteasy-reactive","jaxrs-filter","response-filter","request-context"],"backgroundTag":"filter-phase-violation","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}