apereo/cas · error · FailedLoginException

Radius authentication failed for user

Error message

Radius authentication failed for user ${username}

What it means

In the classic RadiusAuthenticationHandler, when RadiusUtils.authenticateUsernamePassword reports failure (Pair key false) the handler throws FailedLoginException naming the user. This is the normal bad-credential path for RADIUS in CAS core authentication.

Solutions

  1. Verify the user's RADIUS credentials
  2. Check cas.authn.radius server configuration (shared secret, host, authentication port, accounting port)
  3. Configure multiple RADIUS servers and enable failoverOnAuthenticationFailure
  4. Review RADIUS server logs for the reject reason

Example fix

// before
throw new FailedLoginException("Radius authentication failed for user " + username);
// after: enable failover so transient rejects retry
// cas.authn.radius.failover-authentication-failure=true
Defensive patterns

Strategy: try-catch

Try / catch

try {
    authHandler.authenticate(credential);
} catch (FailedLoginException e) {
    // map to bad-credentials error in the login flow
} catch (AccountNotFoundException e) {
    // unknown user path
}

Prevention

When it happens

Trigger: authenticateUsernamePasswordInternal receives result.getKey()==false (or value absent) from RadiusUtils — all RADIUS servers rejected the username/password and failover did not apply.

Common situations: Wrong password at login; RADIUS shared secret/server misconfiguration; account rejected by RADIUS policy; secondary RADIUS servers not configured so failover silently fails.

Understand the failure class

Related errors


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

Appendix: source

Thrown at support/cas-server-support-radius/src/main/java/org/apereo/cas/adaptors/radius/authentication/handler/support/RadiusAuthenticationHandler.java:63

        this.failoverOnException = failoverOnException;
        this.failoverOnAuthenticationFailure = failoverOnAuthenticationFailure;
    }

    @Override
    protected AuthenticationHandlerExecutionResult authenticateUsernamePasswordInternal(final UsernamePasswordCredential credential,
                                                                                        final String originalPassword) throws GeneralSecurityException {

        try {
            val username = credential.getUsername();
            val result = RadiusUtils.authenticate(username, credential.toPassword(), this.servers,
                this.failoverOnAuthenticationFailure, this.failoverOnException, Optional.empty());
            if (result.getKey() && result.getValue().isPresent()) {
                val attributes = CollectionUtils.toMultiValuedMap(result.getValue().get());
                return createHandlerResult(credential,
                    principalFactory.createPrincipal(username, attributes),
                    new ArrayList<>());
            }
            throw new FailedLoginException("Radius authentication failed for user " + username);
        } catch (final Throwable e) {
            LoggingUtils.error(LOGGER, e);
            throw new FailedLoginException("Radius authentication failed " + e.getMessage());
        }
    }
}

View on GitHub (pinned to e7288fc434)