apereo/cas · error · FailedLoginException
sent an unacceptable response status code
Error message
<callbackUrl> sent an unacceptable response status code
What it means
A proxy-authentication attempt failed because the HttpBasedServiceCredential's callback URL did not pass the HTTP reachability check: httpClient.isValidEndPoint() returned false, meaning the callback endpoint responded with an unacceptable/non-2xx status or was unreachable. This is the generic guard for the pgtUrl/proxy-callback validation step of the CAS proxy protocol; the input at fault is the service's callback URL.
Solutions
- Verify the callback URL is reachable from the CAS server and returns HTTP 200
- Check the service's proxy policy configuration to ensure the callback URL is allowed
- Inspect the callback endpoint for outages, TLS issues, or redirects that HttpClient rejects
- Confirm network/firewall rules allow the CAS server to reach the callback host
Defensive patterns
Strategy: try-catch
When it happens
Trigger: Thrown at core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/handler/support/ProxyAuthenticationHandler.java:51 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/2ff0447c9af14925.
Report an issue: GitHub.
Appendix: source
Thrown at core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/handler/support/ProxyAuthenticationHandler.java:51
final Integer order, final HttpClient httpClient) {
super(name, principalFactory, order);
this.httpClient = httpClient;
}
@Override
public AuthenticationHandlerExecutionResult authenticate(final Credential credential, final Service service) throws Throwable {
val httpCredential = (HttpBasedServiceCredential) credential;
if (!httpCredential.getService().getProxyPolicy()
.isAllowedProxyCallbackUrl(httpCredential.getService(), httpCredential.getCallbackUrl())) {
LOGGER.warn("Proxy policy for service [{}] cannot authorize the requested callback url [{}].",
httpCredential.getService(), httpCredential.getCallbackUrl());
throw new FailedLoginException(httpCredential.getCallbackUrl() + " cannot be authorized");
}
LOGGER.debug("Attempting to authenticate [{}]", httpCredential);
val callbackUrl = httpCredential.getCallbackUrl();
if (!httpClient.isValidEndPoint(callbackUrl)) {
throw new FailedLoginException(callbackUrl.toExternalForm() + " sent an unacceptable response status code");
}
val principalId = httpCredential.getCredentialMetadata().getId();
val proxyPrincipal = principalFactory.createPrincipal(principalId);
return new DefaultAuthenticationHandlerExecutionResult(this, httpCredential, proxyPrincipal);
}
@Override
public boolean supports(final Credential credential) {
return credential instanceof HttpBasedServiceCredential;
}
@Override
public boolean supports(final Class<? extends Credential> clazz) {
return HttpBasedServiceCredential.class.isAssignableFrom(clazz);
}
}
View on GitHub (pinned to e7288fc434)