apereo/cas · warning · InvalidCookieException
Invalid cookie . Required remote address does not match
Error message
Invalid cookie %s. Required remote address %s does not match %s
What it means
When geolocation binding is disabled, CAS compares the IP stored in the cookie against the current request's client IP. If they differ and the new IP does not match the configured allowedIpAddressesPattern regex, InvalidCookieException is thrown. The pattern acts as an escape hatch for clients whose IPs legitimately change within known ranges.
Solutions
- Configure allowedIpAddressesPattern with a regex covering the client's legitimate IP ranges (e.g. '192\\.168\\..*')
- Confirm X-Forwarded-For handling so the real client IP is resolved consistently
- Ask affected users to clear cookies and re-login after network changes
- If validation failures are unexpected attacks, keep the strict behavior and monitor logs
Example fix
// before // cas.tgc.pinnable-session-cookie.allowed-ip-addresses-pattern= // after: allow corporate egress ranges // cas.tgc.pinnable-session-cookie.allowed-ip-addresses-pattern=10\\..*|192\\.168\\..*
Defensive patterns
Strategy: validation
Validate before calling
String currentIp = ClientInfoHolder.getClientInfo().getClientIpAddress();
if (!cookieIp.equals(currentIp) && !RegexUtils.find(pattern, currentIp)) {
// will be rejected; clear cookie and re-auth
} Type guard
boolean ipAllowed(String cookieIp, String currentIp, String pattern) {
return cookieIp.equals(currentIp) || RegexUtils.find(pattern, currentIp);
} Try / catch
try { obtainCookieValue(...); } catch (InvalidCookieException e) {
redirectToLogin(); // IP changed beyond allowed pattern
} Prevention
- Set allowedIpAddressesPattern when clients sit behind rotating egress IPs
- Test patterns against both IPv4 and IPv6 forms
- Treat repeated mismatches as possible cookie replay and alert
When it happens
Trigger: cookieClientLocationOrIp != clientInfo.getClientIpAddress() AND (allowedIpAddressesPattern is blank OR RegexUtils.find(pattern, currentIp) is false) — e.g. client switched networks, load balancer presents different egress IP, or allowedIpAddressesPattern not configured despite NAT/proxy IP rotation.
Common situations: Users behind rotating corporate proxies fail validation; admin forgot to set cas.tgc allowed-ip-addresses-pattern; IPv4 cookie vs IPv6 current address comparison mismatch; cookie replayed from a different machine (this error is the intended protection working).
Related errors
- Invalid cookie . Required fields are empty
- Invalid cookie Required remote address does not match
- Invalid cookie . Required user-agent does not match
- Unable to match required remote address
- Invalid cookie . Required user-agent does not match
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/3c213c7bd40f9c0f.
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:137
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)) {
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)