apereo/cas · error · InvalidCookieException
Invalid cookie Required remote address does not match
Error message
Invalid cookie <name> Required remote address <cookieIp> does not match <clientLocation>
What it means
Session pinning with geo-location enabled: the geo-location (or IP) stored in the cookie does not equal the geo-location resolved for the current request's client. The cookie is rejected because the client's apparent location changed since the cookie was issued, which is treated as possible theft/replay of the cookie.
Solutions
- Re-authenticate to obtain a fresh cookie from the current location
- Verify geo-location resolution is consistent/stable; flaky geolocation data causes false positives
- Disable geoLocateClientSession if client roaming is expected and acceptable
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at core/cas-server-core-cookie-api/src/main/java/org/apereo/cas/web/support/mgmr/DefaultCasCookieValueManager.java:128 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/520b495ed789c66d.
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:128
if (Stream.of(cookieValue, cookieClientLocationOrIp, cookieUserAgent).anyMatch(StringUtils::isBlank)) {
throw new InvalidCookieException("Invalid cookie %s. Required fields are empty".formatted(cookieProperties.getName()));
}
val clientInfo = ClientInfoHolder.getClientInfo();
if (clientInfo == null) {
val message = "Unable to match required remote address %s because client ip at time of cookie creation is unknown for cookie %s"
.formatted(cookieProperties.getName(), cookieClientLocationOrIp);
LOGGER.warn(message);
throw new InvalidCookieException(message);
}
if (cookieProperties.isGeoLocateClientSession()) {
val clientLocationOrIp = getClientGeoLocation(clientInfo);
if (!cookieClientLocationOrIp.equals(clientLocationOrIp)) {
val message = "Invalid cookie %s Required remote address %s does not match %s"
.formatted(cookieProperties.getName(), cookieClientLocationOrIp, clientLocationOrIp);
LOGGER.warn(message);
throw new InvalidCookieException(message);
}
} else {
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)) {View on GitHub (pinned to e7288fc434)