{"record":{"id":"c5ea4933f6c493e5","repo":"apereo/cas","slug":"principal-resolution-handled-by-produced-a-nu","errorCode":null,"errorMessage":"Principal resolution handled by [{}] produced a null principal for: [{}]CAS is configured to treat principal resolution failures as fatal.","messagePattern":"Principal resolution handled by \\[(.+?)\\] produced a null principal for: \\[(.+?)\\]CAS is configured to treat principal resolution failures as fatal\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/DefaultAuthenticationManager.java","lineNumber":169,"sourceCode":"                                                   final AuthenticationHandler handler,\n                                                   final Service service) throws Throwable {\n        val clientInfo = ClientInfoHolder.getClientInfo();\n        publishEvent(new CasAuthenticationTransactionStartedEvent(this, credential, clientInfo));\n\n        try {\n            AuthenticationHolder.setCurrentAuthentication(authenticationBuilder.build());\n            val handlerExecutionResult = handler.authenticate(credential, service);\n            val authenticationHandlerName = handler.getName();\n            authenticationBuilder.addSuccess(authenticationHandlerName, handlerExecutionResult);\n            LOGGER.debug(\"Authentication handler [{}] successfully authenticated [{}]\", authenticationHandlerName, credential);\n            publishEvent(new CasAuthenticationTransactionSuccessfulEvent(this, credential, clientInfo));\n            var principal = principalResolver != null\n                ? resolvePrincipal(handler, principalResolver, credential, handlerExecutionResult.getPrincipal(), service)\n                : handlerExecutionResult.getPrincipal();\n            if (principal == null) {\n                val resolverName = principalResolver == null ? authenticationHandlerName : principalResolver.getName();\n                if (this.principalResolutionFailureFatal) {\n                    LOGGER.warn(\"Principal resolution handled by [{}] produced a null principal for: [{}]\"\n                        + \"CAS is configured to treat principal resolution failures as fatal.\", resolverName, credential);\n                    throw new UnresolvedPrincipalException();\n                }\n                LOGGER.warn(\"Principal resolution handled by [{}] produced a null principal. \"\n                    + \"This is likely due to misconfiguration or missing attributes; CAS will attempt to use the principal \"\n                    + \"produced by the authentication handler, if any.\", resolverName);\n            } else {\n                val currentPrincipal = authenticationBuilder.getPrincipal();\n                if (!(currentPrincipal instanceof NullPrincipal)) {\n                    val merger = authenticationSystemSupport.getObject().getPrincipalElectionStrategy().getAttributeMerger();\n                    LOGGER.trace(\"Merging attributes from [{}] into principal [{}]\", principal, currentPrincipal);\n                    val mergedAttributes = CoreAuthenticationUtils.mergeAttributes(currentPrincipal.getAttributes(), principal.getAttributes(), merger);\n                    principal = principal.withAttributes(mergedAttributes);\n                    LOGGER.debug(\"Merged attributes into principal [{}]\", principal);\n                }\n                authenticationBuilder.setPrincipal(principal);\n            }\n            LOGGER.debug(\"Final principal resolved for this authentication event is [{}]\", principal);","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/DefaultAuthenticationManager.java#L151-L187","documentation":"When principal resolution yields a null principal and cas.authn.principalResolutionFailureFatal is true, DefaultAuthenticationManager.authenticateAndResolvePrincipal logs this warning and throws UnresolvedPrincipalException, aborting authentication. CAS is configured to treat a failed resolution as fatal rather than falling back to the handler's principal.","triggerScenarios":"principalResolutionFailureFatal=true and resolvePrincipal (or the handler result itself) returns null — e.g. resolver unsupported credential (see [360]), empty attribute repository result, or handler produced no principal.","commonSituations":"Strict deployments where principal MUST come from the attribute source (LDAP/JDBC) but the attribute repository is down or the user record is missing; misconfigured resolver so resolution silently fails; principal mapping/removal of attributes results in null.","solutions":["Verify the underlying attribute repository (LDAP/JDBC/etc.) has a record for the resolved user.","Set cas.authn.principalResolutionFailureFatal=false to fall back to the handler-produced principal (only if acceptable).","Fix resolver configuration so it supports the credential (see error 360).","Inspect the preceding ERROR log line '[resolver] failed to resolve principal' for the root cause exception."],"exampleFix":"// before\ncas.authn.principal-resolution-failure-fatal=true\n// after (allow fallback to handler principal)\ncas.authn.principal-resolution-failure-fatal=false","handlingStrategy":"try-catch","validationCode":"val resolved = principalResolver.resolve(credential);\nif (resolved == null) {\n    // fix attribute source before enabling fatal mode\n}","typeGuard":null,"tryCatchPattern":"try {\n    authenticationManager.authenticate(transaction);\n} catch (UnresolvedPrincipalException e) {\n    LOGGER.error(\"Principal resolution failed for {}\", transaction.getCredentials(), e);\n    // present a user-friendly failure or repair attribute repository\n}","preventionTips":["Monitor attribute repository health; fatal principal resolution turns an LDAP outage into a total login outage.","Only set principalResolutionFailureFatal=true when attributes are strictly required."],"tags":["authentication","principal-resolution","fatal-config"],"backgroundTag":"principal-resolution-failed","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"}