apereo/cas · warning · InvalidCookieException
Invalid cookie . Required user-agent does not match
Error message
Invalid cookie %s. Required user-agent %s does not match %s
What it means
CAS binds compound cookies to the browser's User-Agent at creation time. During validation, the current request's User-Agent (via HttpRequestUtils.getHttpServletRequestUserAgent) is compared to the stored one; any mismatch rejects the cookie as InvalidCookieException. This mitigates cookie theft to a different client environment.
Solutions
- Disable user-agent binding for the cookie (set the relevant user-agent-check property to false) if UA volatility is causing logouts
- Ensure proxies forward the User-Agent header unchanged
- Re-authenticate after browser upgrades (expected behavior)
- Use consistent clients for automated tests, or copy the same UA header
Example fix
// before: proxy strips header // proxy_set_header User-Agent ""; // after: forward it // proxy_set_header User-Agent $http_user_agent;
Defensive patterns
Strategy: validation
Validate before calling
String agent = HttpRequestUtils.getHttpServletRequestUserAgent(request);
String storedAgent = /* part 3 of compound cookie */;
if (!storedAgent.equals(agent)) { /* cookie will be rejected */ } Type guard
boolean userAgentMatches(String stored, HttpServletRequest req) {
return Objects.equals(stored, HttpRequestUtils.getHttpServletRequestUserAgent(req));
} Try / catch
try { obtainCookieValue(...); } catch (InvalidCookieException e) {
// UA changed (browser update/proxy strip); force re-auth
redirectToLogin();
} Prevention
- Disable user-agent binding if auto-updates cause mass logouts
- Ensure reverse proxies forward User-Agent unchanged
- Use stable UA strings in automated tests
When it happens
Trigger: cookieUserAgent != agent — user upgraded/switched browser mid-session, browser auto-update changed the UA string, CAS is behind a proxy that strips/normalizes the User-Agent header, or the request path receives requests from a non-browser client (curl, health check) carrying the cookie.
Common situations: Browser major-version auto-update invalidates sessions (UA includes version); monitoring scripts replaying cookies; reverse proxy removing User-Agent so agent resolves to null/blank; mobile apps changing UA between app versions.
Related errors
- Invalid cookie . Required user-agent does not match
- Request does not specify a user-agent
- Invalid cookie . Required fields are empty
- Unable to match required remote address
- Invalid cookie Required remote address does not match
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/b133987d82c9365e.
Report an issue: GitHub.
Appendix: source
Thrown at core/cas-server-core-cookie-api/src/main/java/org/apereo/cas/web/support/mgmr/DefaultCasCookieValueManager.java:149
val clientIpAddress = clientInfo.getClientIpAddress();
if (!cookieClientLocationOrIp.equals(clientIpAddress)) {
if (StringUtils.isBlank(cookieProperties.getAllowedIpAddressesPattern())
|| !RegexUtils.find(cookieProperties.getAllowedIpAddressesPattern(), clientIpAddress)) {
val message = "Invalid cookie %s. Required remote address %s does not match %s"
.formatted(cookieProperties.getName(), cookieClientLocationOrIp, clientIpAddress);
LOGGER.warn(message);
throw new InvalidCookieException(message);
}
LOGGER.debug("Required remote address [{}] does not match [{}], but it's authorized to proceed",
cookieClientLocationOrIp, clientIpAddress);
}
}
val agent = HttpRequestUtils.getHttpServletRequestUserAgent(request);
if (!cookieUserAgent.equals(agent)) {
val message = "Invalid cookie %s. Required user-agent %s does not match %s"
.formatted(cookieProperties.getName(), cookieUserAgent, agent);
LOGGER.warn(message);
throw new InvalidCookieException(message);
}
return cookieValue;
}
}
View on GitHub (pinned to e7288fc434)