apache / apache/grails-core

Grails7 java.lang.IllegalStateException:: The request object has been recycled and is no longer associated with this facade

Open
#15,851 0 comments 0 reactions 0 assignees View on GitHub
relates-to:spring-security
Dominant language
Groovy
Stars
2.9k
Forks
975
Avg merge
1d 22h
Merged PRs (30d)
92

Description

### Expected Behavior

no exceptions but I'm not sure why it's showing up, we're not using any `async` operations

### Actual Behaviour

I'm observing the following exception:
```
2025-08-07 12:34:45 http-nio-8080-exec-10 o.a.c.c.C.[.[.[.[dispatcherServletRegistration] ERROR Servlet.service() for servlet [dispatcherServletRegistration] in context with path [] threw exception
java.lang.IllegalStateException: The request object has been recycled and is no longer associated with this facade
at org.apache.catalina.connector.RequestFacade.checkFacade(RequestFacade.java:855)
at org.apache.catalina.connector.RequestFacade.setAttribute(RequestFacade.java:412)
at jakarta.servlet.ServletRequestWrapper.setAttribute(ServletRequestWrapper.java:238)
at jakarta.servlet.ServletRequestWrapper.setAttribute(ServletRequestWrapper.java:238)
at jakarta.servlet.ServletRequestWrapper.setAttribute(ServletRequestWrapper.java:238)
at org.grails.web.util.WebUtils.storeGrailsWebRequest(WebUtils.java:457)
at grails.plugin.springsecurity.web.access.intercept.AnnotationFilterInvocationDefinition.determineUrl(AnnotationFilterInvocationDefinition.groovy:138)
at grails.plugin.springsecurity.web.access.intercept.AbstractFilterInvocationDefinition.getAttributes(AbstractFilterInvocationDefinition.groovy:79)
at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:200)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:125)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
at grails.plugin.springsecurity.web.UpdateRequestContextHolderExceptionTranslationFilter.doFilter(UpdateRequestContextHolderExceptionTranslationFilter.groovy:68)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.groovy:56)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:150)
at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:105)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:179)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:235)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:229)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.groovy:66)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:374)
at org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(IndyInterface.java:321)
```

### Steps To Reproduce

Cannot reproduce this on a small example but it's something to do with upgrading to `spring boot 3` which in turn uses `Tomcat 10`.
Request facade recycling enabled by default.

based on https://github.com/spring-projects/spring-boot/issues/36763 and specifically: https://github.com/spring-projects/spring-boot/issues/36763#issuecomment-1667382305

this can be disabled with :
```
...
container.addConnectorCustomizers(new TomcatConnectorCustomizer() {
@Override
void customize(Connector connector) {
connector.setDiscardFacades(false)
}
})
...
```
or enabled when grails6 and tomcat9 by `connector.setDiscardFacades(true)`

Disabling it resolves the issue but is not recommended. The exception is caused by this line: https://github.com/apache/grails-spring-security/blob/6b504dd2d59cab22d34dbafea8edd8fb1ecb28fb/plugin-core/plugin/src/main/groovy/grails/plugin/springsecurity/web/access/intercept/AnnotationFilterInvocationDefinition.groovy#L138

### Environment Information

_No response_

### Example Application

_No response_

### Version

Grails 7.0.0-M5

Contributor guide

Open the contributing guide

Research direction

Start at AnnotationFilterInvocationDefinition.groovy line 138 and follow its call to WebUtils.storeGrailsWebRequest, using the reported Tomcat 10 request-facade recycling behavior as context. Since the issue has no minimal example, first establish a reproducible request path, then verify that the exception no longer occurs with facade recycling enabled.

Written by the indexing model from the issue text.

Assessment

Tech stack
groovy, spring, spring-boot
Domain
authorization, backend, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.