quarkusio/quarkus · error · AuthenticationFailedException
AuthenticationFailedException
Error message
AuthenticationFailedException
What it means
JpaIdentityProviderUtil.checkPassword verifies the submitted password against the stored Password credential using Elytron's PasswordCredential.verify. When verification fails (wrong password, corrupted stored hash, or missing verifier for the algorithm), it throws AuthenticationFailedException, which Quarkus translates into a 401 response.
Source
Thrown at extensions/security-jpa-common/runtime/src/main/java/io/quarkus/security/jpa/common/runtime/JpaIdentityProviderUtil.java:33
import io.quarkus.security.AuthenticationFailedException;
import io.quarkus.security.identity.request.TrustedAuthenticationRequest;
import io.quarkus.security.identity.request.UsernamePasswordAuthenticationRequest;
import io.quarkus.security.jpa.PasswordType;
import io.quarkus.security.runtime.QuarkusPrincipal;
import io.quarkus.security.runtime.QuarkusSecurityIdentity;
public class JpaIdentityProviderUtil {
private JpaIdentityProviderUtil() {
// utility class used by generated classes
}
public static QuarkusSecurityIdentity.Builder checkPassword(Password storedPassword,
UsernamePasswordAuthenticationRequest request) {
PasswordGuessEvidence sentPasswordEvidence = new PasswordGuessEvidence(request.getPassword().getPassword());
PasswordCredential storedPasswordCredential = new PasswordCredential(storedPassword);
if (!storedPasswordCredential.verify(ProviderUtil.INSTALLED_PROVIDERS, sentPasswordEvidence)) {
throw new AuthenticationFailedException();
}
QuarkusSecurityIdentity.Builder builder = QuarkusSecurityIdentity.builder();
builder.setPrincipal(new QuarkusPrincipal(request.getUsername()));
builder.addCredential(request.getPassword());
return builder;
}
public static QuarkusSecurityIdentity.Builder trusted(TrustedAuthenticationRequest request) {
QuarkusSecurityIdentity.Builder builder = QuarkusSecurityIdentity.builder();
builder.setPrincipal(new QuarkusPrincipal(request.getPrincipal()));
return builder;
}
public static void addRoles(QuarkusSecurityIdentity.Builder builder, String roles) {
if (roles.indexOf(',') != -1) {
for (String role : roles.split(",")) {
builder.addRole(role.trim());
}View on GitHub (pinned to e1c734241f)
Solutions
- Verify the user is submitting the correct username/password.
- Confirm @Password(type=...) matches how the password is actually stored (plain text vs MCF string like bcrypt/argon2).
- Re-store or reset the password so it is encoded consistently with the configured PasswordType.
- For CUSTOM types, ensure the password provider's getPassword returns a Password the installed Elytron providers can verify.
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check stored format matches configured type, e.g. for MCF:
if (passwordType == PasswordType.MCF && !stored.startsWith("$"))
log.warn("Stored password is not an MCF string; checkPassword will fail"); Try / catch
try {
securityIdentity = identityProvider.authenticate(request).await().indefinitely();
} catch (AuthenticationFailedException e) {
// return 401 / prompt retry; do not leak whether user exists
return Uni.createFrom().item(HttpCredentialTransport.ChallengeKind.HEADER_AUTZ);
} Prevention
- Match @Password type to actual storage format (plain vs MCF).
- Encode passwords with the same algorithm/parameters used at verification.
- For CUSTOM types, register needed Elytron providers.
- Never store/reset a password in a different format than configured.
When it happens
Trigger: A UsernamePasswordAuthenticationRequest is processed and PasswordCredential.verify(ProviderUtil.INSTALLED_PROVIDERS, sentPasswordEvidence) returns false — i.e. the supplied password does not match the stored CLEAR/MCF/custom-provided Password.
Common situations: User typing a wrong password; stored hash created with different parameters or a different algorithm; the password column holding a plain value while PasswordType.MCF is configured (or vice versa); provider not installed for custom password algorithms.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- No IdentityProviders were registered to handle Authenticatio
- No AnonymousIdentityProvider registered. An instance of Anon
- Unknown password type: ${passwordType}
- You can only annotate one field or method with @${annotation
- The role element type must be indexed by Jandex: ${elementTy
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/ffd906169bf5e81f.
Report an issue: GitHub.