{"record":{"id":"ba612f53fbe48b67","repo":"apereo/cas","slug":"principal-resolution-handled-by-produced-a-nu-ba612f","errorCode":null,"errorMessage":"Principal resolution handled by [{}] produced a null principal. This is likely due to misconfiguration or missing attributes; CAS will attempt to use the principal produced by the authentication handler, if any.","messagePattern":"Principal resolution handled by \\[(.+?)\\] produced a null principal\\. This is likely due to misconfiguration or missing attributes; CAS will attempt to use the principal produced by the authentication handler, if any\\.","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":173,"sourceCode":"\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);\n            publishEvent(new CasAuthenticationPrincipalResolvedEvent(this, Objects.requireNonNull(principal), clientInfo));\n        } finally {\n            AuthenticationHolder.clear();\n        }","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/DefaultAuthenticationManager.java#L155-L191","documentation":"Non-fatal variant of the null-principal warning: principal resolution returned null, principalResolutionFailureFatal is false, so CAS logs that this is likely misconfiguration or missing attributes and will try to use the principal produced by the authentication handler, if any. Authentication continues but attributes may be incomplete.","triggerScenarios":"resolvePrincipal returns null with principalResolutionFailureFatal=false; e.g. resolver unsupported credential, empty attribute query results, or handler produced no principal either.","commonSituations":"Attribute repository has no entry for the authenticated user; filter/query in attribute repository excludes the user; resolver credential mismatch (like 360) in lenient deployments; partially migrated configs after CAS version upgrades.","solutions":["Check attribute repository configuration and confirm the user record exists and matches the query/filter.","Fix the resolver so it supports the credential type emitted by the handler.","Verify the authentication handler produces a usable principal, since CAS will fall back to it.","If missing principals are unacceptable, set cas.authn.principal-resolution-failure-fatal=true."],"exampleFix":"// before\ncas.authn.ldap[0].search-filter=(uid={user})  // user not present in that OU\n// after\ncas.authn.ldap[0].search-filter=(&(uid={user})(objectClass=person))  // corrected filter/base DN","handlingStrategy":"validation","validationCode":"val attrs = attributeRepository.getPerson(user).getAttributes();\nif (attrs.isEmpty()) {\n    LOGGER.warn(\"No attributes found for {} — principal resolution will be null\", user);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Test search filters and base DNs against the live directory regularly.","Decide explicitly whether handler-produced principals are an acceptable fallback."],"tags":["authentication","principal-resolution","attributes"],"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"}