spring-projects/spring-security · error · DataIntegrityViolationException
Series Id '<series>' already exists!
Error message
Series Id '<series>' already exists!
What it means
InMemoryTokenRepositoryImpl.createNewToken refuses to overwrite an existing series and throws DataIntegrityViolationException when a PersistentRememberMeToken with the same series id is already stored. The repository mirrors the uniqueness constraint a persistent store would enforce on the series primary key.
Source
Thrown at web/src/main/java/org/springframework/security/web/authentication/rememberme/InMemoryTokenRepositoryImpl.java:42
import org.jspecify.annotations.Nullable;
import org.springframework.dao.DataIntegrityViolationException;
/**
* Simple <tt>PersistentTokenRepository</tt> implementation backed by a Map. Intended for
* testing only.
*
* @author Luke Taylor
*/
public class InMemoryTokenRepositoryImpl implements PersistentTokenRepository {
private final Map<String, PersistentRememberMeToken> seriesTokens = new HashMap<>();
@Override
public synchronized void createNewToken(PersistentRememberMeToken token) {
PersistentRememberMeToken current = this.seriesTokens.get(token.getSeries());
if (current != null) {
throw new DataIntegrityViolationException("Series Id '" + token.getSeries() + "' already exists!");
}
this.seriesTokens.put(token.getSeries(), token);
}
@Override
public synchronized void updateToken(String series, String tokenValue, Date lastUsed) {
PersistentRememberMeToken token = getTokenForSeries(series);
if (token == null) {
throw new IllegalArgumentException("Token for series '" + series + "' does not exist");
}
PersistentRememberMeToken newToken = new PersistentRememberMeToken(token.getUsername(), series, tokenValue,
new Date());
// Store it, overwriting the existing one.
this.seriesTokens.put(series, newToken);
}
@Override
public synchronized @Nullable PersistentRememberMeToken getTokenForSeries(String seriesId) {View on GitHub (pinned to 96852e8860)
Solutions
- Call updateToken instead of createNewToken when the series may already exist.
- Remove the existing series first with removeToken/removeUserTokens before re-creating.
- Use JdbcTokenRepositoryImpl (with the DDL's primary key) for durable storage; treat this exception as a duplicate-key condition and generate a new series id.
- In tests, use a fresh InMemoryTokenRepositoryImpl per test or clear state in setup.
Example fix
// before
repository.createNewToken(new PersistentRememberMeToken(user, existingSeries, value, new Date()));
// after
if (repository.getTokenForSeries(existingSeries) != null) {
repository.removeUserTokens(user);
}
repository.createNewToken(new PersistentRememberMeToken(user, UUID.randomUUID().toString(), value, new Date())); Defensive patterns
Strategy: try-catch
Validate before calling
if (repo.getTokenForSeries(token.getSeries()) != null) {
throw new IllegalStateException("series already exists: " + token.getSeries());
} Try / catch
try {
repo.createNewToken(token);
} catch (DataIntegrityViolationException e) {
repo.updateToken(token.getSeries(), token.getTokenValue(), token.getDate());
} Prevention
- Generate series ids with UUID.randomUUID() to avoid collisions
- Use updateToken for existing series, createNewToken only for new ones
- In tests, create a fresh InMemoryTokenRepositoryImpl per test
- Prefer a persistent repository (Jdbc) that enforces the same uniqueness explicitly
When it happens
Trigger: Calling createNewToken(token) twice with tokens having the same getSeries() value — typically because application code (not the framework) creates tokens manually, or two threads/instances share the same series generation without going through the repository's normal flow.
Common situations: Custom remember-me bootstrap code re-creating a token for an existing series; seeding the in-memory repository from a database that already contains the series; test code that forgets to clear the repository between cases; switching repositories (Jdbc vs InMemory) mid-flight.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- Token for series '<series>' does not exist
- Can not set rememberMeCookieName and custom rememberMeServic
- The presented RememberMeAuthenticationToken does not contain
- Cookie token was not Base64 encoded; value was '<cookieValue
- Cookie token did not contain 2 tokens, but contained '[cooki
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/a12687eec88effab.
Report an issue: GitHub.