apereo/cas · warning
Client [ ] is rejected for authentication based on country…
Error message
Client [{}] is rejected for authentication based on country location What it means
DefaultAdaptiveAuthenticationPolicy rejects an authentication request because the client's resolved geolocation country appears in cas.authn.adaptive.policy.reject-countries. This is a WARN log plus a 'false' return from isAuthenticationRequestAllowed, which the adaptive policy engine turns into an authentication block. It means geo-location data matched a deliberately configured blacklist.
Solutions
- Remove the client's country from cas.authn.adaptive.policy.reject-countries, or have the user disable their VPN/proxy
- Verify the geoIP database (MaxMind) is current and correctly located; update or fix cas.geo-location settings
- If blanket country blocking is unintended, remove/reduce the reject-countries entry or disable the adaptive policy feature
Example fix
// before cas.authn.adaptive.policy.reject-countries=DE,FR // after cas.authn.adaptive.policy.reject-countries=
Defensive patterns
Strategy: validation
Validate before calling
if (policy != null && policy.getRejectCountries() != null && geoService.locate(clientIp, null) != null) { /* check country not in rejectCountries before calling */ } Type guard
boolean isCountryAllowed(GeoLocationService svc, String ip, List<String> rejected) { var loc = svc.locate(ip, null); return loc == null || rejected == null || !rejected.contains(loc.getCountry()); } Prevention
- Keep reject-countries minimal and review after geoIP database updates
- Test authentication from representative IPs/VPN exits before deploying
- Pin and regularly refresh the MaxMind database
When it happens
Trigger: Authentication attempt whose client IP resolves via geoLocationService.locate() to a country listed in adaptiveAuthenticationProperties.getPolicy().getRejectCountries().
Common situations: Users behind VPNs/proxies exiting in a blocked country; misconfigured reject-countries list accidentally including the users' own country; stale or wrong GeoLite2 database attributing the wrong country; server-side NAT making all clients appear from one region.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Client IP [ ] is banned
- No client IP or user-agent was provided. Skipping adaptive…
- Client IP [ ] is rejected for authentication
- User agent [ ] is rejected for authentication
- Client IP [ ] is rejected for authentication because…
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/7ea4c27e8bbb3d8b.
Report an issue: GitHub.
Appendix: source
Thrown at core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/adaptive/DefaultAdaptiveAuthenticationPolicy.java:58
}
val clientIp = clientInfo.getClientIpAddress();
if (isIpAddressRejected(requestContext, clientIp)) {
LOGGER.warn("Client IP [{}] is rejected for authentication", clientIp);
return false;
}
if (isUserAgentRejected(userAgent)) {
LOGGER.warn("User agent [{}] is rejected for authentication", userAgent);
return false;
}
LOGGER.debug("User agent [{}] is authorized to proceed", userAgent);
if (this.geoLocationService != null && location != null && StringUtils.isNotBlank(clientIp)
&& StringUtils.isNotBlank(this.adaptiveAuthenticationProperties.getPolicy().getRejectCountries())) {
val loc = this.geoLocationService.locate(clientIp, location);
if (loc != null) {
LOGGER.debug("Determined geolocation for [{}] to be [{}]", clientIp, loc);
if (isGeoLocationCountryRejected(loc)) {
LOGGER.warn("Client [{}] is rejected for authentication based on country location", clientIp);
return false;
}
} else {
LOGGER.info("Could not determine geolocation for [{}]", clientIp);
}
}
LOGGER.debug("Adaptive authentication policy has authorized client [{}] to proceed.", clientIp);
return true;
}
private boolean isGeoLocationCountryRejected(final GeoLocationResponse finalLoc) {
val rejectCountries = this.adaptiveAuthenticationProperties.getPolicy().getRejectCountries();
return StringUtils.isNotBlank(rejectCountries)
&& RegexUtils.find(rejectCountries, finalLoc.build());
}
private boolean isUserAgentRejected(final String userAgent) {
val rejectBrowsers = this.adaptiveAuthenticationProperties.getPolicy().getRejectBrowsers();View on GitHub (pinned to e7288fc434)