apereo/cas · error · InvalidCookieException
Unable to match required address
Error message
Unable to match required address <ip> because client ip at time of cookie creation is unknown for cookie <name>
What it means
The cookie was pinned to the client's IP (or geo-location) at creation time, but ClientInfoHolder.getClientInfo() returned null for the current request, so there is no client IP to compare against the address stored in the cookie. Session-pinning validation cannot proceed, and the cookie is rejected rather than trusted blindly — a defensive check against replay from an unverifiable context.
Solutions
- Ensure the request flows through the CAS webflow/servlet pipeline so ClientInfoHolder is populated
- Check that any filter which sets ClientInfo (e.g., ClientInfoThreadLocalFilter) runs before cookie validation
- If session pinning cannot be supported for this path, disable pinToSession for the cookie
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:119 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/6a4b0ebf9ceaf050.
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:119
return cookieValue;
}
if (cookieParts.size() != COOKIE_FIELDS_LENGTH) {
throw new InvalidCookieException("Invalid cookie %s. Required fields are missing".formatted(cookieProperties.getName()));
}
val cookieClientLocationOrIp = cookieParts.get(1);
val cookieUserAgent = cookieParts.get(2);
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);View on GitHub (pinned to e7288fc434)