apereo/cas · critical · AuthenticationException
Resolved credentials for this transaction are empty
Error message
Resolved credentials for this transaction are empty
What it means
DefaultAuthenticationManager.authenticateInternal throws AuthenticationException when the AuthenticationTransaction contains no credentials. This indicates the credential-extraction step upstream resolved to an empty set, so there is nothing to authenticate against the handler execution plan.
Solutions
- Inspect the incoming request and ensure credential parameters (username/password or token) are actually submitted.
- Verify the credential extractors (e.g. cas.authn.accept.credentials-extractor or the flow's form object) match the request parameter names.
- If building the transaction programmatically, ensure you call TransactionBuilder.bind(...) with at least one credential.
- Check for recently changed custom extractors/filters that drop credentials; restore them or return the original credential.
- Enable DEBUG logging for org.apereo.cas.authentication to trace the resolved credentials list.
Example fix
// before AuthenticationTransaction.with(service).collect(); // no credentials bound // after AuthenticationTransaction.with(service).bind(credential).collect();
Defensive patterns
Strategy: validation
Validate before calling
// before invoking the authentication manager
var creds = transaction.getCredentials();
if (creds == null || creds.isEmpty()) {
throw new InvalidRequestException("No credentials bound to the authentication transaction");
} Try / catch
try {
return authenticationManager.authenticate(transaction);
} catch (AuthenticationException e) {
if (e.getMessage().contains("credentials for this transaction are empty")) {
LOGGER.error("Login request carried no credentials; check form/extractor parameter names", e);
}
throw e;
} Prevention
- Add webflow/form validation rejecting empty login submissions before authentication.
- Keep credential extractor parameter names in sync with the login form fields.
- Write an integration test asserting a credential-less request fails early and observably.
When it happens
Trigger: Invoking the AuthenticationManager with an AuthenticationTransaction whose getCredentials() is empty — e.g. a login flow that posted no credential parameters (missing username/password fields), or a custom credential extractor that filtered out the credentials before the transaction was built.
Common situations: Webflow misconfiguration where the login form binds to different parameter names than the extractors expect; custom AuthenticationTransaction created manually with no credentials; API/REST authentication request missing body parameters; extractor beans disabled by feature conditions.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- No credentials can be extracted to authenticate the REST…
- Unable to extract credentials for multifactor authentication
- No credentials are provided or extracted to authenticate…
- [ ] Caused by: [ ]
- Provided credentials chain is empty as no credentials have…
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/5faa4098e3bd2d9a.
Report an issue: GitHub.
Appendix: source
Thrown at core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/DefaultAuthenticationManager.java:216
protected Collection<AuthenticationMetaDataPopulator> getAuthenticationMetadataPopulatorsForTransaction(
final AuthenticationTransaction transaction) {
return authenticationEventExecutionPlan.getAuthenticationMetadataPopulators(transaction);
}
protected void publishEvent(final ApplicationEvent event) {
if (applicationContext != null) {
applicationContext.publishEvent(event);
}
}
protected AuthenticationBuilder authenticateInternal(final AuthenticationTransaction transaction) throws Throwable {
val credentials = transaction.getCredentials();
LOGGER.debug("Authentication credentials provided for this transaction are [{}]", credentials);
if (credentials.isEmpty()) {
LOGGER.error("Resolved authentication handlers for this transaction are empty");
throw new AuthenticationException("Resolved credentials for this transaction are empty");
}
val authenticationBuilder = new DefaultAuthenticationBuilder(NullPrincipal.getInstance());
credentials.forEach(authenticationBuilder::addCredential);
val handlerSet = authenticationEventExecutionPlan.resolveAuthenticationHandlers(transaction);
LOGGER.debug("Candidate resolved authentication handlers for this transaction are [{}]", handlerSet);
try {
for (val credential : credentials) {
LOGGER.debug("Attempting to authenticate credential [{}]", credential);
val itHandlers = handlerSet.iterator();
var proceedWithNextHandler = true;
while (proceedWithNextHandler && itHandlers.hasNext()) {
val handler = itHandlers.next();
if (handler.supports(credential)) {
try {View on GitHub (pinned to e7288fc434)