{"record":{"id":"5caa54feefca0089","repo":"apereo/cas","slug":"could-not-authenticate-provided-credentials","errorCode":null,"errorMessage":"Could not authenticate provided credentials","messagePattern":"Could not authenticate provided credentials","errorType":"exception","errorClass":"BadCredentialsException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-ldap-core/src/main/java/org/apereo/cas/authorization/EndpointLdapAuthenticationProvider.java","lineNumber":112,"sourceCode":"                entry.getAttributes().forEach(attribute -> attributes.put(attribute.getName(), new ArrayList<>(attribute.getStringValues())));\n                val principal = PrincipalFactoryUtils.newPrincipalFactory().createPrincipal(username, attributes);\n                val authZGen = buildAuthorizationGenerator();\n                val authorities = authZGen.apply(Objects.requireNonNull(principal));\n\n                LOGGER.debug(\"List of authorities remapped from profile roles are [{}]\", authorities);\n                if (authorities.stream().anyMatch(authority -> requiredRoles.contains(authority.getAuthority()))) {\n                    return generateAuthenticationToken(authentication, authorities);\n                }\n                LOGGER.warn(\"User [{}] is not authorized to access the requested resource\", username);\n            } else {\n                LOGGER.warn(\"LDAP authentication response produced no results for [{}]\", username);\n            }\n\n        } catch (final Throwable e) {\n            LoggingUtils.error(LOGGER, e);\n            throw new InsufficientAuthenticationException(\"Unexpected LDAP error\", e);\n        }\n        throw new BadCredentialsException(\"Could not authenticate provided credentials\");\n    }\n\n    @Override\n    public boolean supports(final Class<?> aClass) {\n        return UsernamePasswordAuthenticationToken.class.isAssignableFrom(aClass);\n    }\n\n    private Function<Principal, List<SimpleGrantedAuthority>> buildAuthorizationGenerator() {\n        val properties = ldapProperties.getLdapAuthz();\n\n        if (isGroupBasedAuthorization()) {\n            LOGGER.debug(\"Handling LDAP authorization based on groups\");\n            return new LdapUserGroupsToRolesAuthorizationGenerator(\n                ldapAuthorizationGeneratorUserSearchOperation(),\n                properties.isAllowMultipleResults(),\n                properties.getGroupAttribute(),\n                properties.getGroupPrefix(),\n                ldapAuthorizationGeneratorGroupSearchOperation());","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-ldap-core/src/main/java/org/apereo/cas/authorization/EndpointLdapAuthenticationProvider.java#L94-L130","documentation":"When the LDAP authentication completes without a thrown exception but yields no successful result — no response results, or none containing a resolved entry/authenticated user — the provider throws BadCredentialsException(\"Could not authenticate provided credentials\") as its final statement.","triggerScenarios":"authenticate() runs to completion, no Throwable is thrown, but authenticator.authenticate(request) returns a response with zero results (user does not exist, filter does not match) or an unauthenticated result.","commonSituations":"Typo in username/password for a real user; user does not exist under the configured base DN; user-filter does not match the entry; account exists but bind DN cannot read it; password simply wrong.","solutions":["Verify the username exists in LDAP and matches the user filter under the configured base DN","Double-check the supplied password","Run ldapsearch with the same base DN and filter to confirm the entry is visible to the bind account","Confirm the user is not disabled/locked (directories often return no-result style failures)","Adjust base-dn/user-filter if the entry lives elsewhere"],"exampleFix":"// before\n// user-filter=(uid={user}) but directory keys on sAMAccountName\n// after\n// user-filter=(sAMAccountName={user})","handlingStrategy":"validation","validationCode":"// confirm the user exists before attempting endpoint auth\nSearchResult entry = LdapUtils.getLdapEntry(props, \"(sAMAccountName=\" + user + \")\");\nboolean userExists = entry != null;","typeGuard":null,"tryCatchPattern":"try {\n    provider.authenticate(token);\n} catch (BadCredentialsException e) {\n    // treat as invalid username/password — do NOT retry, return 401\n}","preventionTips":["Verify usernames and passwords out-of-band with ldapsearch whoami bind tests","Keep user-filter aligned with the directory naming attribute","Check the base DN includes the user's OU","Handle disabled/locked accounts, which often surface as no-results"],"tags":["ldap","bad-credentials","authentication"],"backgroundTag":"bad-credentials","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}