{"record":{"id":"6f20a41a024211b4","repo":"quarkusio/quarkus","slug":"csrffilter-should-have-set-the-attribute-csrfform","errorCode":null,"errorMessage":"CSRFFilter should have set the attribute {csrfFormFieldName}, but it is null","messagePattern":"CSRFFilter should have set the attribute (.+?), but it is null","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/resteasy-reactive/rest-csrf/runtime/src/main/java/io/quarkus/csrf/reactive/runtime/CsrfTokenParameterProvider.java","lineNumber":43,"sourceCode":"    private final String csrfHeaderName;\n\n    public CsrfTokenParameterProvider(RestCsrfConfigHolder configHolder) {\n        RestCsrfConfig config = configHolder.getConfig();\n        this.csrfFormFieldName = config.formFieldName();\n        this.csrfCookieName = config.cookieName();\n        this.csrfHeaderName = config.tokenHeaderName();\n    }\n\n    /**\n     * Gets the CSRF token value.\n     *\n     * @throws IllegalStateException if the {@link RoutingContext} does not contain a CSRF token value.\n     */\n    public String getToken() {\n        String token = (String) context.get(CSRF_TOKEN_KEY);\n\n        if (token == null) {\n            throw new IllegalStateException(\n                    \"CSRFFilter should have set the attribute \" + csrfFormFieldName + \", but it is null\");\n        }\n\n        return token;\n    }\n\n    /**\n     * Gets the name of the form parameter that is to contain the value returned by {@link #getToken()}.\n     */\n    public String getParameterName() {\n        return csrfFormFieldName;\n    }\n\n    /**\n     * Gets the CSRF cookie name.\n     */\n    public String getCookieName() {\n        return csrfCookieName;","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/resteasy-reactive/rest-csrf/runtime/src/main/java/io/quarkus/csrf/reactive/runtime/CsrfTokenParameterProvider.java#L25-L61","documentation":"CsrfTokenParameterProvider.getToken() reads the CSRF token from the RoutingContext, where the CSRFFilter was expected to have stored it before form parameter resolution. If the attribute is absent (null), the framework cannot bind the CSRF form field, so an IllegalStateException is thrown at request time.","triggerScenarios":"Injecting/using `CsrfTokenParameterProvider` (e.g. via @RestForm CSRF binding) on a request that never passed through CsrfReactiveFilter — e.g. the route is outside the CSRF filter's protection, or CSRF protection is disabled/misconfigured while form binding still expects the token.","commonSituations":"Calling an endpoint with `@RestForm` CSRF token binding without including the filter (quarkus-rest-csrf config or path exclusion mistakes); a GET/other route pattern that bypasses CsrfReactiveFilter; custom routing registered before the CSRF filter.","solutions":["Ensure `quarkus-rest-csrf` is present and CSRF protection enabled (default) so CsrfReactiveFilter runs on the request path","Verify the request actually passes through the CSRF filter (check `quarkus.rest-csrf.cookie-name`/create-token-path config and route ordering)","Include a valid CSRF token field in the form post; fetch it from the CsrfController/token endpoint rendered with the form","If you don't need CSRF binding, remove the CsrfTokenParameterProvider usage / @RestForm CSRF field from that endpoint"],"exampleFix":"// before\n<form method=\"post\">\n  <input name=\"field1\">\n</form>\n// after\n<form method=\"post\">\n  <input type=\"hidden\" name=\"csrf-token\" th:value=\"{csrfToken}\">\n  <input name=\"field1\">\n</form>","handlingStrategy":"try-catch","validationCode":"String token = routingContext.get(CSRF_TOKEN_KEY); if (token == null) { LOG.warn(\"CSRF token not set by filter — ensure CsrfReactiveFilter ran on this route\"); }","typeGuard":null,"tryCatchPattern":"try { String csrfToken = csrfTokenParameterProvider.getToken(); renderForm(csrfToken); } catch (IllegalStateException e) { LOG.error(\"CSRF filter did not populate token — check quarkus-rest-csrf setup/route ordering\", e); throw e; }","preventionTips":["Keep quarkus-rest-csrf enabled on all form-posting routes","Always include the CSRF hidden field in forms","Do not reorder routing so the CSRF filter is bypassed","Verify the token arrives before @RestForm binding"],"tags":["csrf","rest-csrf","request-lifecycle","quarkus"],"backgroundTag":"missing-csrf-token","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}