apereo/cas · error · FailedLoginException

not in allowed range.

Error message

 not in allowed range.

What it means

RemoteAddressAuthenticationHandler authenticates purely by checking whether the client's IP address falls within the configured allowed IP ranges. When the address is known but outside every configured RemoteAddressIpRangePattern (or the host is unresolvable, swallowed as a debug UnknownHost), it throws FailedLoginException '<address> not in allowed range.'

Solutions

  1. Add the client's actual IP/subnet to cas.authn.remote-address.ip-range (e.g., 192.168.1.0/24)
  2. If behind a proxy, ensure the credential receives the forwarded client IP (configure the proxy/extractor to use X-Forwarded-For), not the proxy's address
  3. Verify range syntax in the configured RemoteAddressIpRangePattern entries (correct CIDR/netmask format)
  4. If a hostname was configured, confirm DNS resolution on the CAS host — unresolvable hosts are silently treated as failures

Example fix

// before (application.properties)
cas.authn.remote-address.ip-range=10.0.0.0/24
// after — include the actual client subnet
cas.authn.remote-address.ip-range=10.0.0.0/24,192.168.10.0/24
Defensive patterns

Strategy: validation

Validate before calling

// pre-check before invoking the handler
val ranges = casProps.getAuthn().getRemoteAddress().getIpRange();
val clientIp = request.getRemoteAddr();
if (ranges.stream().noneMatch(r -> new RemoteAddressIpRangePattern(r).matches(clientIp)))
    LOGGER.warn("Client {} is outside configured remote-address ranges", clientIp);

Try / catch

try {
    result = remoteAddressHandler.authenticate(remoteCredential);
} catch (FailedLoginException e) {
    return fallbackToPrimaryAuthHandler(credential);
}

Prevention

When it happens

Trigger: authenticate() resolves the RemoteAuthenticationCredential's remote address, iterates the configured cas.authn.remote-address.ip-range patterns, none matches (or UnknownHostException is caught and dropped through), so the final statement throws FailedLoginException.

Common situations: CAS deployed behind a reverse proxy so the credential carries the proxy/load-balancer IP instead of the client's (X-Forwarded-For not honored); subnet/CIDR configured too narrowly; network renumbering moving clients out of the allowed range; DNS unable to resolve when the entry was configured as a hostname.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/1d1d7d3adecda8f5. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-generic-remote-webflow/src/main/java/org/apereo/cas/adaptors/generic/remote/RemoteAddressAuthenticationHandler.java:93

        LOGGER.debug("[{}] is in [{}]/[{}]", ip, network, netmask);
        return true;
    }

    @Override
    public AuthenticationHandlerExecutionResult authenticate(final Credential credential, final Service service) throws Throwable {
        val addressCredential = (RemoteAuthenticationCredential) credential;
        if (this.inetNetmask != null && this.inetNetworkRange != null) {
            try {
                val inetAddress = InetAddress.getByName(addressCredential.getRemoteAddress().trim());
                if (containsAddress(this.inetNetworkRange, this.inetNetmask, inetAddress)) {
                    return new DefaultAuthenticationHandlerExecutionResult(this, addressCredential,
                        principalFactory.createPrincipal(addressCredential.getId()));
                }
            } catch (final UnknownHostException e) {
                LOGGER.debug("Unknown host [{}]", addressCredential.getRemoteAddress());
            }
        }
        throw new FailedLoginException(addressCredential.getRemoteAddress() + " not in allowed range.");
    }

    @Override
    public boolean supports(final Credential credential) {
        return credential instanceof RemoteAuthenticationCredential;
    }

    @Override
    public boolean supports(final Class<? extends Credential> clazz) {
        return RemoteAuthenticationCredential.class.isAssignableFrom(clazz);
    }

    /**
     * Sets ip network range.
     *
     * @param ipAddressRange the IP address range that should be allowed trusted logins
     */
    public void configureIpNetworkRange(final String ipAddressRange) {

View on GitHub (pinned to e7288fc434)