apereo/cas · warning
Could not locate service definition by id
Error message
Could not locate service definition by id [{}] What it means
RegisteredServicesEndpoint.deleteService() attempts to resolve the requested service id into a Service via the service factory and look it up in the ServicesManager. When no registered service matches, it logs this warning and returns HTTP 404 (notFound) instead of deleting anything. It signals that the delete target simply does not exist in the registry.
Solutions
- List existing services (GET on the services endpoint) and confirm the id before deleting
- Use the exact numeric id assigned by CAS, not the serviceId URL pattern
- Check whether the service was deleted by another admin or another node in the cluster
- Verify the service registry storage (JSON/JDBC/etc.) is reachable and not reset between calls
Example fix
// before
delete("/cas/v1/services/1234");
// after: verify existence first
val all = get("/cas/v1/services");
if (containsId(all, 1234)) delete("/cas/v1/services/1234"); Defensive patterns
Strategy: validation
Validate before calling
// GET /cas/v1/services first and assert the id exists before DELETE
val exists = listServiceIds().contains(targetId);
if (!exists) throw new Error('service ' + targetId + ' not found'); Type guard
function isDeleted(resp) { return resp.status === 404; } Try / catch
val resp = delete(url);
if (resp.status === 404) { /* treat as already-deleted / stale id */ } Prevention
- Always list services before deleting
- Use the numeric CAS service id, not the serviceId URL
- In clusters, route management calls to one node or use a shared registry
When it happens
Trigger: DELETE request to the CAS services management REST endpoint with an id (or service-id string) that does not match any service currently loaded in ServicesManager; also when the id cannot be converted into a Service by the configured ServiceFactory.
Common situations: Deleting a service that was already removed or never imported; using the numeric CAS id vs the serviceId URL interchangeably; multiple CAS nodes with divergent service registries (one node deleted it first); typo or stale bookmarked id.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- Could not locate account for
- Unable to accept response status
- <policy status exception>
- No credentials can be extracted to authenticate the REST…
- Unable to extract credentials for multifactor authentication
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/8c3fed515529a5f1.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-reports-core/src/main/java/org/apereo/cas/web/report/RegisteredServicesEndpoint.java:219
MEDIA_TYPE_SPRING_BOOT_V2_JSON,
MEDIA_TYPE_SPRING_BOOT_V3_JSON,
MEDIA_TYPE_CAS_YAML
})
public ResponseEntity<String> deleteService(@PathVariable final String id) {
if (NumberUtils.isDigits(id)) {
val svc = servicesManager.getObject().findServiceBy(Long.parseLong(id));
if (svc != null) {
return ResponseEntity.ok(MAPPER.writeValueAsString(servicesManager.getObject().delete(svc)));
}
} else {
val svc = servicesManager.getObject().findServiceBy(
configurationContext.getObject().getServiceFactory().createService(id));
if (svc != null) {
return ResponseEntity.ok(MAPPER.writeValueAsString(
servicesManager.getObject().delete(svc)));
}
}
LOGGER.warn("Could not locate service definition by id [{}]", id);
return ResponseEntity.notFound().build();
}
/**
* Import services.
*
* @param request the request
* @return the http status
* @throws Exception the exception
*/
@PostMapping(path = "/import", consumes = {
MediaType.APPLICATION_OCTET_STREAM_VALUE,
MediaType.APPLICATION_JSON_VALUE,
MediaType.APPLICATION_YAML_VALUE,
MEDIA_TYPE_SPRING_BOOT_V2_JSON,
MEDIA_TYPE_SPRING_BOOT_V3_JSON,
MEDIA_TYPE_CAS_YAML
}, produces = {View on GitHub (pinned to e7288fc434)