{"record":{"id":"f73c4d6b55f50d80","repo":"apereo/cas","slug":"cas-cannot-use-as-the-principal-attribute-id","errorCode":null,"errorMessage":"CAS cannot use [{}] as the principal attribute id, since the profile attributes do not contain the attribute. Either adjust the CAS configuration to use a different attribute, or contact the authentication provider noted by [{}] to release the expected attribute to CAS","messagePattern":"CAS cannot use \\[(.+?)\\] as the principal attribute id, since the profile attributes do not contain the attribute\\. Either adjust the CAS configuration to use a different attribute, or contact the authentication provider noted by \\[(.+?)\\] to release the expected attribute to CAS","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"support/cas-server-support-pac4j-core-clients/src/main/java/org/apereo/cas/support/pac4j/authentication/handler/support/BaseDelegatedClientAuthenticationHandler.java","lineNumber":132,"sourceCode":"                        id = firstAttribute.get().toString();\n                        id = typePrincipalId(id, profile);\n                    }\n                    LOGGER.debug(\"Authentication indicates usage of client principal attribute [{}] for the identifier [{}]\", principalAttribute, id);\n                } else {\n                    LOGGER.warn(\"Authentication cannot find attribute [{}] to use as principal id\", principalAttribute);\n                }\n            } else {\n                LOGGER.warn(\"No custom principal attribute was provided by the client [{}]. Using the default id [{}]\", client, id);\n            }\n        } else if (StringUtils.isNotBlank(principalAttributeId)) {\n            if (profile.containsAttribute(principalAttributeId)) {\n                val firstAttribute = CollectionUtils.firstElement(profile.getAttribute(principalAttributeId));\n                if (firstAttribute.isPresent()) {\n                    id = firstAttribute.get().toString();\n                    id = typePrincipalId(id, profile);\n                }\n            } else {\n                LOGGER.warn(\"CAS cannot use [{}] as the principal attribute id, since the profile attributes do not contain the attribute. \"\n                    + \"Either adjust the CAS configuration to use a different attribute, or contact the authentication provider noted by [{}] \"\n                    + \"to release the expected attribute to CAS\", principalAttributeId, profile.getAttributes());\n            }\n            LOGGER.debug(\"Authentication indicates usage of attribute [{}] for the identifier [{}]\", principalAttributeId, id);\n        } else if (isTypedIdUsed) {\n            id = profile.getTypedId();\n            LOGGER.debug(\"Authentication indicates usage of typed profile id [{}]\", id);\n        }\n        LOGGER.debug(\"Final principal id determined based on client [{}] and user profile [{}] is [{}]\", profile, client, id);\n        return id;\n    }\n\n    private String typePrincipalId(final String id, final UserProfile profile) {\n        return isTypedIdUsed\n            ? profile.getClass().getName() + Pac4jConstants.TYPED_ID_SEPARATOR + id\n            : id;\n    }\n","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-pac4j-core-clients/src/main/java/org/apereo/cas/support/pac4j/authentication/handler/support/BaseDelegatedClientAuthenticationHandler.java#L114-L150","documentation":"BaseDelegatedClientAuthenticationHandler.determinePrincipalIdFrom warns when the CAS-level principalAttributeId (handler configuration) is non-blank but the pac4j profile does not contain that attribute. CAS cannot derive the principal id from it and keeps the default identifier; the message advises fixing CAS config or asking the provider to release the attribute.","triggerScenarios":"cas.authn.pac4j.core.principal-attribute-id (or equivalent handler setting) is set, profile.containsAttribute(principalAttributeId) is false during determinePrincipalIdFrom after provider authentication.","commonSituations":"Global principal attribute configured for all providers but only some IdPs release it; provider changed claim names (e.g. Azure AD userPrincipalName vs mail); attribute not requested in scopes; typo in configuration.","solutions":["Make the provider release the configured attribute (OIDC scopes/claims, OAuth scopes, SAML attribute release/filtering policy).","Change cas.authn.pac4j...principal-attribute-id to an attribute the provider actually returns (verify by logging profile.getAttributes()).","Remove the principal-attribute-id setting so the provider's default identifier is used."],"exampleFix":"// before\ncas.authn.pac4j.core.principal-attribute-id=upn\n// after\ncas.authn.pac4j.core.principal-attribute-id=email","handlingStrategy":"validation","validationCode":"if (StringUtils.isNotBlank(principalAttributeId) && !profile.containsAttribute(principalAttributeId)) {\n    throw new IllegalStateException(\"Configured principal attribute \" + principalAttributeId + \" missing from provider profile: \" + profile.getAttributes());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer provider-specific principal-attribute-id settings over one global attribute.","Test delegated login per provider after changing attribute configuration."],"tags":["pac4j","delegated-authentication","principal-attribute","attribute-release"],"backgroundTag":"attribute-not-released","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"}