apereo/cas · error · UnauthorizedServiceException

Service [ ] is not found in service registry.

Error message

Service [%s] is not found in service registry.

What it means

BaseServiceAuthorizationCheckAction (webflow) resolves the incoming service in the ServicesManager; if no registered service matches, it throws UnauthorizedServiceException.denied('Service [%s] is not found in service registry.'). CAS refuses to process login flows for services that are not registered.

Solutions

  1. Register the service (or fix its serviceId regex) so findServiceBy matches the exact incoming URL
  2. Verify the service registry backend is populated and reachable; check the JSON directory/LDAP config
  3. Inspect cas.log for service-registry load warnings at startup
  4. If testing locally, add an entry matching the exact URL (e.g. ^https://localhost:8443/app/.*$)

Example fix

// before
"serviceId": "^https://app.example.org:8080/login"
// after (client now runs on 8443)
"serviceId": "^https://app.example.org:8443/login"
Defensive patterns

Strategy: validation

Validate before calling

// Client-side precheck: ensure your service URL is registered
RegisteredService rs = servicesManager.findServiceBy(service);
if (rs == null) {
    throw new IllegalStateException("Register service first: " + service.getId());
}

Try / catch

try {
    flow.exec(authorizationCheck);
} catch (UnauthorizedServiceException e) {
    logger.error("Unregistered service: {}", e.getMessage());
    // show 'service not allowed' page or register the service
}

Prevention

When it happens

Trigger: A login/validation request arrives with a service URL that matches no registeredService pattern (findServiceBy returns null); also triggered when the service registry is empty or failed to load.

Common situations: Application's callback URL changed (port, path, protocol) and no registry entry matches; service registry backend (JSON dir, LDAP, Mongo) unreachable or empty; wildcard eval-type mismatch (exact vs regex); typo in serviceId pattern.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/ffe7930a44aa98d9. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-actions-core/src/main/java/org/apereo/cas/web/flow/BaseServiceAuthorizationCheckAction.java:41

 */
@Slf4j
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
public abstract class BaseServiceAuthorizationCheckAction extends BaseCasWebflowAction {
    private final ServicesManager servicesManager;

    private final AuthenticationServiceSelectionPlan authenticationRequestServiceSelectionStrategies;

    @Override
    protected @Nullable Event doExecuteInternal(final RequestContext context) {
        val serviceInContext = WebUtils.getService(context);
        val service = FunctionUtils.doUnchecked(() -> authenticationRequestServiceSelectionStrategies.resolveService(serviceInContext));
        if (service == null) {
            return success();
        }
        val registeredService = servicesManager.findServiceBy(service);
        if (registeredService == null) {
            val msg = String.format("Service [%s] is not found in service registry.", service.getId());
            LOGGER.warn(msg);
            throw UnauthorizedServiceException.denied(msg);
        }
        if (!registeredService.getAccessStrategy().isServiceAccessAllowed(registeredService, service)) {
            val msg = String.format("Service Management: Unauthorized Service Access. "
                + "Service [%s] is not allowed access via the service registry.", service.getId());
            LOGGER.warn(msg);
            WebUtils.putUnauthorizedRedirectUrlIntoFlowScope(context,
                registeredService.getAccessStrategy().getUnauthorizedRedirectUrl());
            throw UnauthorizedServiceException.denied(msg);
        }
        val delegatedPolicy = registeredService.getAccessStrategy().getDelegatedAuthenticationPolicy();
        WebUtils.putCasLoginFormViewable(context, delegatedPolicy == null || !delegatedPolicy.isExclusive());
        return success();
    }
}

View on GitHub (pinned to e7288fc434)