quarkusio/quarkus · error · IllegalStateException
CSRFFilter should have set the attribute {csrfFormFieldName}
Error message
CSRFFilter should have set the attribute {csrfFormFieldName}, but it is null What it means
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.
Source
Thrown at extensions/resteasy-reactive/rest-csrf/runtime/src/main/java/io/quarkus/csrf/reactive/runtime/CsrfTokenParameterProvider.java:43
private final String csrfHeaderName;
public CsrfTokenParameterProvider(RestCsrfConfigHolder configHolder) {
RestCsrfConfig config = configHolder.getConfig();
this.csrfFormFieldName = config.formFieldName();
this.csrfCookieName = config.cookieName();
this.csrfHeaderName = config.tokenHeaderName();
}
/**
* Gets the CSRF token value.
*
* @throws IllegalStateException if the {@link RoutingContext} does not contain a CSRF token value.
*/
public String getToken() {
String token = (String) context.get(CSRF_TOKEN_KEY);
if (token == null) {
throw new IllegalStateException(
"CSRFFilter should have set the attribute " + csrfFormFieldName + ", but it is null");
}
return token;
}
/**
* Gets the name of the form parameter that is to contain the value returned by {@link #getToken()}.
*/
public String getParameterName() {
return csrfFormFieldName;
}
/**
* Gets the CSRF cookie name.
*/
public String getCookieName() {
return csrfCookieName;View on GitHub (pinned to e1c734241f)
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
Example fix
// before
<form method="post">
<input name="field1">
</form>
// after
<form method="post">
<input type="hidden" name="csrf-token" th:value="{csrfToken}">
<input name="field1">
</form> Defensive patterns
Strategy: try-catch
Validate before calling
String token = routingContext.get(CSRF_TOKEN_KEY); if (token == null) { LOG.warn("CSRF token not set by filter — ensure CsrfReactiveFilter ran on this route"); } Try / catch
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; } Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- {what} must not be null
- CSRF must not be null
- Please add an extension that provides a CSRF prevention feat
- Async can only be started once
- A generic type is not allowed here; try creating a subclass
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/6f20a41a024211b4.
Report an issue: GitHub.