spring-projects/spring-security · warning · InvalidCookieException
Cookie token was not Base64 encoded; value was '<cookieValue
Error message
Cookie token was not Base64 encoded; value was '<cookieValue>'
What it means
AbstractRememberMeServices.decodeCookie Base64-decodes the remember-me cookie value before splitting it into tokens. If the value is not valid Base64, Base64.getDecoder() throws IllegalArgumentException which is rethrown as InvalidCookieException so the invalid cookie can be rejected (and typically cancelled).
Source
Thrown at web/src/main/java/org/springframework/security/web/authentication/rememberme/AbstractRememberMeServices.java:220
}
/**
* Decodes the cookie and splits it into a set of token strings using the ":"
* delimiter.
* @param cookieValue the value obtained from the submitted cookie
* @return the array of tokens.
* @throws InvalidCookieException if the cookie was not base64 encoded.
*/
protected String[] decodeCookie(String cookieValue) throws InvalidCookieException {
for (int j = 0; j < cookieValue.length() % 4; j++) {
cookieValue = cookieValue + "=";
}
String cookieAsPlainText;
try {
cookieAsPlainText = new String(Base64.getDecoder().decode(cookieValue.getBytes()));
}
catch (IllegalArgumentException ex) {
throw new InvalidCookieException("Cookie token was not Base64 encoded; value was '" + cookieValue + "'");
}
String[] tokens = StringUtils.delimitedListToStringArray(cookieAsPlainText, DELIMITER);
for (int i = 0; i < tokens.length; i++) {
tokens[i] = URLDecoder.decode(tokens[i], StandardCharsets.UTF_8);
}
return tokens;
}
/**
* Inverse operation of decodeCookie.
* @param cookieTokens the tokens to be encoded.
* @return base64 encoding of the tokens concatenated with the ":" delimiter.
*/
protected String encodeCookie(String[] cookieTokens) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < cookieTokens.length; i++) {
sb.append(URLEncoder.encode(cookieTokens[i], StandardCharsets.UTF_8));
if (i < cookieTokens.length - 1) {View on GitHub (pinned to 96852e8860)
Solutions
- Clear the invalid cookie in the browser (or have the app call cancelCookie on InvalidCookieException, which the default implementation does) and log in again.
- Verify the client sets the cookie exactly as the server returned it, without decoding/encoding or trimming '=' padding.
- Check intermediary infrastructure (proxies, WAFs) for cookie rewriting.
- If you generate remember-me cookies yourself, encode with Base64.getEncoder().encodeToString(...).
Example fix
// before cookie.setValue(username + ":" + token); // not Base64 -> InvalidCookieException // after cookie.setValue(Base64.getEncoder().encodeToString((username + ":" + token).getBytes(StandardCharsets.UTF_8)));
Defensive patterns
Strategy: try-catch
Validate before calling
boolean isBase64(String v) {
try { Base64.getDecoder().decode(v.getBytes(StandardCharsets.UTF_8)); return true; }
catch (IllegalArgumentException e) { return false;
} Type guard
boolean isValidRememberMeCookie(Cookie c) {
return c != null && c.getValue() != null
&& c.getValue().matches("[A-Za-z0-9+/]+=*");
} Try / catch
try {
Authentication a = rememberMeServices.autoLogin(request, response);
} catch (InvalidCookieException e) {
((AbstractRememberMeServices) rememberMeServices).cancelCookie(request, response);
// continue unauthenticated
} Prevention
- Never rewrite/trim the cookie value client-side; store exactly what the server set
- Watch for proxies/WAFs mangling cookies and fix them server-side
- After changing remember-me key/implementation, invalidate old cookies
- Keep the default cancelCookie-on-invalid behavior so bad cookies are cleared automatically
When it happens
Trigger: Calling decodeCookie (via the cookieTokens extraction path of autoLogin) with a cookie value that contains characters outside the Base64 alphabet, or that has been tampered with, truncated, or otherwise corrupted in transit.
Common situations: Manual cookie manipulation; a proxy or application server rewriting/truncating the cookie; client code writing the cookie without Base64 encoding; leftover cookies from an older scheme after upgrading the remember-me implementation or changing the encoding.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Cookie token did not contain 2 tokens, but contained '[cooki
- Cookie token did not contain 3 or 4 tokens, but contained '[
- Cookie token[1] has expired (expired on '<expiryDate>'; curr
- Cookie token[1] did not contain a valid number (contained '"
- Can not set rememberMeCookieName and custom rememberMeServic
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/6a127cc976d51f2b.
Report an issue: GitHub.