{"record":{"id":"d38e7f41ddba012f","repo":"apereo/cas","slug":"service-definition-is-undefined-or-it-s-not-a","errorCode":null,"errorMessage":"Service definition [{}] is undefined or it's not an OpenId Connect relying party","messagePattern":"Service definition \\[(.+?)\\] is undefined or it's not an OpenId Connect relying party","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"support/cas-server-support-oidc-services/src/main/java/org/apereo/cas/services/PairwiseOidcRegisteredServiceUsernameAttributeProvider.java","lineNumber":53,"sourceCode":" * @author Misagh Moayyed\n * @since 5.2.0\n */\n@Slf4j\n@Getter\n@NoArgsConstructor\n@EqualsAndHashCode(callSuper = true)\n@Setter\npublic class PairwiseOidcRegisteredServiceUsernameAttributeProvider extends BaseRegisteredServiceUsernameAttributeProvider {\n\n    @Serial\n    private static final long serialVersionUID = 469929103943101717L;\n\n    private PersistentIdGenerator persistentIdGenerator = new OidcPairwisePersistentIdGenerator();\n\n    @Override\n    public String resolveUsernameInternal(final RegisteredServiceUsernameProviderContext context) {\n        if (context.getRegisteredService() == null || !OidcRegisteredService.class.isAssignableFrom(context.getRegisteredService().getClass())) {\n            LOGGER.warn(\"Service definition [{}] is undefined or it's not an OpenId Connect relying party\", context.getRegisteredService());\n            return context.getPrincipal().getId();\n        }\n        val oidcSvc = (OidcRegisteredService) context.getRegisteredService();\n        if (StringUtils.isBlank(oidcSvc.getSubjectType())\n            || Strings.CI.equals(OidcSubjectTypes.PUBLIC.getType(), oidcSvc.getSubjectType())) {\n            LOGGER.warn(\"Service definition [{}] does not request a pairwise subject type\", oidcSvc);\n            return context.getPrincipal().getId();\n        }\n        val sectorIdentifier = getSectorIdentifier(oidcSvc);\n        val id = this.persistentIdGenerator.generate(context.getPrincipal(), sectorIdentifier);\n        LOGGER.debug(\"Resolved username [{}] for pairwise access\", id);\n        return id;\n    }\n\n    private static @Nullable String getSectorIdentifier(final OidcRegisteredService client) {\n        if (StringUtils.isNotBlank(client.getSectorIdentifierUri())) {\n            val uri = UriComponentsBuilder.fromUriString(client.getSectorIdentifierUri()).build();\n            return uri.getHost();","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-oidc-services/src/main/java/org/apereo/cas/services/PairwiseOidcRegisteredServiceUsernameAttributeProvider.java#L35-L71","documentation":"PairwiseOidcRegisteredServiceUsernameAttributeProvider.resolveUsernameInternal checks that the registered service is an OidcRegisteredService before generating a pairwise subject identifier. If the service is null or of another type, it logs this warning and falls back to the raw principal id, meaning pairwise (per-sector persistent) subject behavior is silently not applied.","triggerScenarios":"Assigning the pairwise username attribute provider to a non-OIDC registered service (e.g. a plain OAuth or CAS service), or resolving the username during processing where the service definition failed to load (null context.getRegisteredService()).","commonSituations":"Copy-pasting a username attribute provider configuration between service types; service registry returning a generic RegisteredService; misconfigured service JSON missing @class OidcRegisteredService.","solutions":["Make sure the service is registered as an OidcRegisteredService (correct @class in the service JSON).","Remove the pairwise username provider from non-OIDC services; use a suitable provider instead.","Verify the service registry entry loads correctly (service id/name) so context.getRegisteredService() is not null."],"exampleFix":"// before\n\"@class\": \"org.apereo.cas.services.RegisteredServiceImpl\"\n// after\n\"@class\": \"org.apereo.cas.services.OidcRegisteredService\"","handlingStrategy":"type-guard","validationCode":"if (registeredService == null || !(registeredService instanceof OidcRegisteredService)) {\n    throw new IllegalArgumentException(\"Pairwise provider requires an OidcRegisteredService\");\n}","typeGuard":"boolean isOidcService(RegisteredService svc) {\n    return svc instanceof OidcRegisteredService;\n}","tryCatchPattern":null,"preventionTips":["Use correct @class in service JSON when enabling pairwise subjects","Only attach pairwise username providers to OIDC services","Validate service definitions in the management app before saving"],"tags":["oidc","pairwise","registered-service","type-mismatch"],"backgroundTag":"invalid-argument-value","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"}