{"record":{"id":"cd458b8e7cd318e1","repo":"apereo/cas","slug":"no-security-token-could-be-retrieved-for-service","errorCode":null,"errorMessage":"No security token could be retrieved for service [{}] and principal [{}]","messagePattern":"No security token could be retrieved for service \\[(.+?)\\] and principal \\[(.+?)\\]","errorType":"exception","errorClass":"UnauthorizedServiceException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-ws-idp/src/main/java/org/apereo/cas/ws/idp/web/WSFederationValidateRequestCallbackController.java","lineNumber":110,"sourceCode":"        val assertion = validateRequestAndBuildCasAssertion(response, request, fedRequest);\n        val securityTokenReq = getSecurityTokenFromRequest(request);\n        val securityToken = FunctionUtils.doIfNull(securityTokenReq,\n                Unchecked.supplier(() -> {\n                    LOGGER.debug(\"No security token is yet available. Invoking security token service to issue token\");\n                    return fetchSecurityTokenFromAssertion(assertion, targetService);\n                }),\n                () -> securityTokenReq)\n            .get();\n        addSecurityTokenTicketToRegistry(request, securityToken);\n        val rpToken = produceRelyingPartyToken(request, targetService, fedRequest, securityToken, assertion);\n        return postResponseBackToRelyingParty(rpToken, fedRequest);\n    }\n\n    private SecurityToken fetchSecurityTokenFromAssertion(final TicketValidationResult assertion, final Service targetService) throws Throwable {\n        val principal = assertion.getPrincipal().getId();\n        val token = getConfigContext().getSecurityTokenServiceTokenFetcher().fetch(targetService, principal);\n        if (token.isEmpty()) {\n            LOGGER.warn(\"No security token could be retrieved for service [{}] and principal [{}]\", targetService, principal);\n            throw UnauthorizedServiceException.denied(\"Denied: %s\".formatted(targetService.getId()));\n        }\n        return token.get();\n    }\n\n    private void addSecurityTokenTicketToRegistry(final HttpServletRequest request,\n                                                  final SecurityToken securityToken) throws Throwable {\n        LOGGER.trace(\"Creating security token as a ticket to CAS ticket registry...\");\n        val ticketRegistry = getConfigContext().getTicketRegistry();\n        val tgt = CookieUtils.getTicketGrantingTicketFromRequest(getConfigContext().getTicketGrantingTicketCookieGenerator(),\n            ticketRegistry, request);\n        val serializedToken = SerializationUtils.serialize(securityToken);\n\n        val securityTokenTicketFactory = (SecurityTokenTicketFactory) getConfigContext().getTicketFactory().get(SecurityTokenTicket.class);\n        val ticket = securityTokenTicketFactory.create(tgt, serializedToken);\n        LOGGER.trace(\"Created security token ticket [{}]\", ticket);\n        ticketRegistry.addTicket(ticket);\n        LOGGER.trace(\"Added security token as a ticket to CAS ticket registry...\");","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-ws-idp/src/main/java/org/apereo/cas/ws/idp/web/WSFederationValidateRequestCallbackController.java#L92-L128","documentation":"After ticket validation the callback controller asks the SecurityTokenServiceTokenFetcher to fetch a security token for the validated service and principal; the fetch returned empty, so the controller throws UnauthorizedServiceException.denied(). The token service could not issue/locate a token for this relying party.","triggerScenarios":"fetchSecurityTokenFromAssertion(): securityTokenServiceTokenFetcher.fetch(targetService, principal) yields Optional.empty() (typically because invokeSecurityTokenServiceForToken returned null) and the empty case triggers this warning plus the exception.","commonSituations":"Downstream STS endpoint unreachable or misconfigured so token issuance returns null; WS-Federation registered service missing required token configuration (token type, signing cert); principal id invalid for token claims; STS backend error swallowed into an empty Optional.","solutions":["Check the STS client configuration for the registered service (endpoint, token type, signing credentials)","Verify the STS backend is reachable and healthy at fetch time; inspect earlier ERROR logs","Confirm the registered service is a correctly configured WSFederationRegisteredService with token issuance enabled","Retry the federation flow; if intermittent, look for STS/network timeouts"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (getConfigContext().getSecurityTokenServiceTokenFetcher().fetch(service, principalId).isEmpty()) { /* token issuance will fail */ }","typeGuard":null,"tryCatchPattern":"try { return fetchSecurityTokenFromAssertion(assertion, service); }\ncatch (UnauthorizedServiceException e) { /* check STS config/reachability for this service */ throw e; }","preventionTips":["Validate STS endpoint, token type, and signing credentials per registered service","Health-check the STS before deploying federation flows","Inspect prior logs for the root cause of the empty token fetch"],"tags":["ws-federation","security-token","unauthorized-service","sts"],"backgroundTag":"empty-api-response","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"}