The problem stemmed from using "response.sendError(...)", which triggered a new request to /error that was intercepted by the next filter in the chain. I opted to simplify the code, I replaced ".defaultAuthenticationEntryPointFor(...)" with ".authenticationEntryPoint(new HttpStatusEntryPoint(HttpStatus.UNAUTHORIZED))".