{"record":{"id":"5dfa02e985a4dd3d","repo":"apereo/cas","slug":"service-s-is-not-found-in-service-registry-5dfa02","errorCode":null,"errorMessage":"Service [%s] is not found in service registry.","messagePattern":"Service \\[(.+?)\\] is not found in service registry\\.","errorType":"exception","errorClass":"UnauthorizedServiceException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-validation-core/src/main/java/org/apereo/cas/web/AbstractServiceValidateController.java","lineNumber":64,"sourceCode":" * validation services. Receive back an Assertion containing the user Principal\n * and (possibly) a chain of Proxy Principals. Store the Assertion in the Model\n * and chain to a View to generate the appropriate response (CAS 1, CAS 2 XML,\n * SAML, ...).\n *\n * @author Scott Battaglia\n * @author Misagh Moayyed\n * @since 3.0.0\n */\n@Slf4j\n@Getter\n@RequiredArgsConstructor(access = AccessLevel.PROTECTED)\npublic abstract class AbstractServiceValidateController extends AbstractDelegateController {\n    private final ServiceValidateConfigurationContext serviceValidateConfigurationContext;\n\n    private static void verifyRegisteredServiceProperties(final RegisteredService registeredService, final Service service) {\n        if (registeredService == null) {\n            val msg = String.format(\"Service [%s] is not found in service registry.\", service.getId());\n            LOGGER.warn(msg);\n            throw UnauthorizedServiceException.denied(msg);\n        }\n        if (!registeredService.getAccessStrategy().isServiceAccessAllowed(registeredService, service)) {\n            val msg = String.format(\"ServiceManagement: Unauthorized Service Access. \"\n                + \"Service [%s] is not enabled in the CAS service registry.\", service.getId());\n            LOGGER.warn(msg);\n            throw UnauthorizedServiceException.denied(msg);\n        }\n    }\n\n    protected Ticket handleProxyGrantingTicketDelivery(final String serviceTicketId, final Credential credential) throws Throwable {\n        val serviceTicket = serviceValidateConfigurationContext.getTicketRegistry().getTicket(serviceTicketId, ServiceTicket.class);\n        val authenticationResult = serviceValidateConfigurationContext.getAuthenticationSystemSupport()\n            .finalizeAuthenticationTransaction(serviceTicket.getService(), credential);\n        val proxyGrantingTicket = serviceValidateConfigurationContext.getCentralAuthenticationService()\n            .createProxyGrantingTicket(serviceTicketId, authenticationResult);\n        LOGGER.debug(\"Generated proxy-granting ticket [{}] off of service ticket [{}] and credential [{}]\",\n            proxyGrantingTicket.getId(), serviceTicketId, credential);","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-validation-core/src/main/java/org/apereo/cas/web/AbstractServiceValidateController.java#L46-L82","documentation":"During /serviceValidate (or /p3/serviceValidate) the requested service could not be matched to any registered service in the CAS service registry, so verifyRegisteredServiceProperties throws UnauthorizedServiceException.denied. CAS refuses to validate tickets for unregistered services.","triggerScenarios":"getServiceCredentialsFromRequest extracts the service from the request, looks it up via ServicesManager, and passes the result to verifyRegisteredServiceProperties; the null branch fires when no registered service matches the passed service id/url (or registry lookup returns nothing).","commonSituations":"Client app URL not registered in the CAS service registry; regex/exact-match pattern in the registry entry doesn't match the actual service parameter (trailing slash, http vs https, port); service registry changes not yet replicated (registry sync delay or cache not refreshed).","solutions":["Register the exact service URL (or a matching pattern) in the CAS service registry via the management console or JSON registry file, then ensure the registry is loaded.","Verify the service parameter sent by the client matches the registry entry character-for-character (scheme, host, port, path) or adjust the pattern to a regex that covers it.","If the registry entry exists, check the registry cache/replication and call the services management endpoints or restart to force a reload."],"exampleFix":"// JSON service registry: before (entry missing)\n// after: create /etc/cas/services/myApp-10000001.json\n{\n  \"@class\": \"org.apereo.cas.services.RegisteredService\",\n  \"serviceId\": \"^https://myapp\\.example\\.org/.*\",\n  \"id\": 10000001,\n  \"name\": \"MyApp\",\n  \"evaluationOrder\": 1\n}","handlingStrategy":"validation","validationCode":"// client side, before calling /serviceValidate\n// ensure the service is registered and matches a registry pattern exactly\nconst registered = [\"^https:\\/\\/myapp\\.example\\.org\\/.*\"];\nif (!registered.some(p => new RegExp(p).test(serviceUrl))) {\n  throw new Error(`Service ${serviceUrl} is not registered in CAS`);\n}","typeGuard":null,"tryCatchPattern":"try {\n    // validate ticket against CAS\n} catch (UnauthorizedServiceException e) {\n    // registry lookup failed: check service registry entry and URL match\n}","preventionTips":["Register every client service URL before deploying the client integration.","Prefer regex serviceId patterns (e.g. ^https://app\\.example\\.org/.*) to absorb path variations.","Confirm the exact scheme/host/port/path the client sends matches the registry entry.","Watch for service registry sync delays in clustered registry backends."],"tags":["service-registry","ticket-validation","unauthorized-service","cas-protocol"],"backgroundTag":"record-not-found","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"}