spring-projects/spring-security · error · RememberMeAuthenticationException
Autologin failed due to data access problem
Error message
Autologin failed due to data access problem
What it means
PersistentTokenBasedRememberMeServices wraps any exception raised while persisting the rotated remember-me token (series/token value/date) into a RememberMeAuthenticationException with this message. The library cannot guarantee auto-login correctness if the new token cannot be written, so it aborts the remember-me authentication. The original data-access exception is logged via logger.error("Failed to update token: ", ex).
Source
Thrown at web/src/main/java/org/springframework/security/web/authentication/rememberme/PersistentTokenBasedRememberMeServices.java:133
"PersistentTokenBasedRememberMeServices.cookieStolen",
"Invalid remember-me token (Series/token) mismatch. Implies previous cookie theft attack."));
}
if (token.getDate().getTime() + getTokenValiditySeconds() * 1000L < System.currentTimeMillis()) {
throw new RememberMeAuthenticationException("Remember-me login has expired");
}
// Token also matches, so login is valid. Update the token value, keeping the
// *same* series number.
this.logger.debug(LogMessage.format("Refreshing persistent login token for user '%s', series '%s'",
token.getUsername(), token.getSeries()));
PersistentRememberMeToken newToken = new PersistentRememberMeToken(token.getUsername(), token.getSeries(),
generateTokenData(), new Date());
try {
this.tokenRepository.updateToken(newToken.getSeries(), newToken.getTokenValue(), newToken.getDate());
addCookie(newToken, request, response);
}
catch (Exception ex) {
this.logger.error("Failed to update token: ", ex);
throw new RememberMeAuthenticationException("Autologin failed due to data access problem");
}
return getUserDetailsService().loadUserByUsername(token.getUsername());
}
/**
* Creates a new persistent login token with a new series number, stores the data in
* the persistent token repository and adds the corresponding cookie to the response.
*
*/
@Override
protected void onLoginSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication successfulAuthentication) {
String username = successfulAuthentication.getName();
this.logger.debug(LogMessage.format("Creating new persistent login for user %s", username));
PersistentRememberMeToken persistentToken = new PersistentRememberMeToken(username, generateSeriesData(),
generateTokenData(), new Date());
try {
this.tokenRepository.createNewToken(persistentToken);View on GitHub (pinned to 96852e8860)
Solutions
- Check application logs for the 'Failed to update token: ' cause to identify the underlying data-access exception
- Verify the persistent_logins table exists with columns username, series, token_value, last_used matching the schema in the reference docs
- Confirm the DataSource used by JdbcTokenRepositoryImpl (or custom PersistentTokenRepository) is healthy and reachable
- If using an in-memory/custom repository, ensure updateToken handles unknown series gracefully and that concurrent logins are not deleting rows
- As a last resort clear stale cookies and have users log in again
Example fix
// before
@Bean
public PersistentTokenRepository tokenRepository(DataSource ds) {
JdbcTokenRepositoryImpl repo = new JdbcTokenRepositoryImpl();
repo.setDataSource(ds); // table missing -> updateToken fails at autologin
return repo;
}
// after
@Bean
public PersistentTokenRepository tokenRepository(DataSource ds) {
JdbcTokenRepositoryImpl repo = new JdbcTokenRepositoryImpl();
repo.setDataSource(ds);
repo.setCreateTableOnStartup(true); // creates persistent_logins if absent
return repo;
} Defensive patterns
Strategy: try-catch
Validate before calling
// verify repository/table before autologin is relied upon
try (Connection c = dataSource.getConnection();
PreparedStatement ps = c.prepareStatement("SELECT 1 FROM persistent_logins LIMIT 1")) {
ps.executeQuery();
} catch (SQLException e) {
throw new IllegalStateException("persistent_logins table unavailable", e);
} Type guard
boolean isTokenRepositoryHealthy(PersistentTokenRepository repo) {
return repo != null; // plus a DB connectivity probe at startup
} Try / catch
try {
SecurityContext ctx = SecurityContextHolder.getContext();
// ... auto-login flow
} catch (RememberMeAuthenticationException e) {
logger.warn("Remember-me autologin failed; falling back to login page", e);
response.sendRedirect("/login");
} Prevention
- Apply the reference schema for persistent_logins at deploy time
- Monitor DB connectivity and pool exhaustion alerts
- Don't delete token rows on every logout if multiple devices share the account
- Log the underlying cause from 'Failed to update token:' and alert on it
When it happens
Trigger: processAutoLoginCookie calls tokenRepository.updateToken(series, tokenValue, date) during automatic login; if that call throws (DB down, table missing, constraint violation, connection timeout), the catch block rethrows this RememberMeAuthenticationException.
Common situations: Remember-me persistence table (persistent_logins) missing or schema mismatch; database connection pool exhausted or DB unreachable; the series row was deleted concurrently (another device logged in and rotated the token); JdbcTemplate token repository misconfigured with a broken DataSource.
Related errors
- Cookie token did not contain 3 or 4 tokens, but contained '[
- RunAsImplAuthenticationProvider.incorrectKey
- Authenticated principal required to operate with ACLs
- Unable to find ACL information for object identity '{oid}'
- Object identity '{objectIdentity}' already exists
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/0c941cc7d4f922af.
Report an issue: GitHub.