apereo/cas · error · InvalidCookieException

Invalid cookie . Required remote address does not match

Error message

Invalid cookie <name>. Required remote address <cookieIp> does not match <clientIp>

What it means

Session pinning by IP: the client IP stored in the cookie does not match the current request's client IP, and no allowedIpAddressesPattern on the cookie config authorizes the new address. The cookie is rejected as a possible cookie-theft/replay from a different machine or network (e.g., NAT/proxy change, mobile network switch).

Solutions

  1. Clear the cookie and re-authenticate
  2. If the client legitimately changes IPs (NAT pools, VPNs), configure cas.cookie...allowedIpAddressesPattern to allow them
  3. Disable pinToSession for this cookie if IP stability cannot be guaranteed
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:138 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/605eeb818cbd6fcc. 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:138

        }

        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)