apereo/cas · warning

[ ] is not found at the path specified

Error message

[{}] is not found at the path specified

What it means

In load(File), after the readability check, CAS verifies file.exists(). If the file disappeared (deleted between scan and load, or a stale path was passed), it logs this warning and returns an empty list — no service is loaded from it.

Solutions

  1. Verify the path exists (ls the directory) before calling load; correct any path typos.
  2. If a script deletes/renames files, let the registry watcher handle removal instead of calling load on stale handles.
  3. Restart the registry load or call serviceRegistry.load() (no-arg) to rescan the whole directory.

Example fix

// before
serviceRegistry.load(new File("/etc/cas/config/services/1001-app.json")); // file moved
// after
File f = new File("/etc/cas/config/services/1001-app.json");
if (f.exists()) { serviceRegistry.load(f); }
Defensive patterns

Strategy: validation

Validate before calling

File f = new File(path);
if (!f.exists()) {
    throw new NoSuchFileException(f.getAbsolutePath());
}

Prevention

When it happens

Trigger: Calling serviceRegistry.load(file) with a File object whose path no longer exists; the directory watcher fires for a file that was already removed.

Common situations: Race between file deletion and the resource watcher; hand-editing scripts that move/rename service files while CAS runs; typo'd absolute path passed to load().

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at core/cas-server-core-services-registry/src/main/java/org/apereo/cas/services/resource/AbstractResourceBasedServiceRegistry.java:271

                        BaseResourceBasedRegisteredServiceWatcher.LOG_SERVICE_DUPLICATE.accept(s2);
                        return s1;
                    }, LinkedHashMap::new));
            val listedServices = new ArrayList<>(this.services.values());
            val results = registeredServiceReplicationStrategy.updateLoadedRegisteredServicesFromCache(listedServices, this);
            results.forEach(service -> publishEvent(new CasRegisteredServiceLoadedEvent(this, service, clientInfo)));
            return results;
        });
    }

    @Override
    public Collection<RegisteredService> load(final File file) {
        val fileName = file.getName();
        if (!file.canRead()) {
            LOGGER.warn("[{}] is not readable. Check file permissions", fileName);
            return new ArrayList<>();
        }
        if (!file.exists()) {
            LOGGER.warn("[{}] is not found at the path specified", fileName);
            return new ArrayList<>();
        }
        if (file.length() == 0) {
            LOGGER.debug("[{}] appears to be empty so no service definition will be loaded", fileName);
            return new ArrayList<>();
        }
        if (!fileName.isEmpty() && fileName.charAt(0) == '.') {
            LOGGER.debug("[{}] starts with ., ignoring", fileName);
            return new ArrayList<>();
        }
        if (Arrays.stream(getExtensions()).noneMatch(fileName::endsWith)) {
            LOGGER.debug("[{}] doesn't end with valid extension, ignoring", fileName);
            return new ArrayList<>();
        }

        if (!RegexUtils.matches(this.serviceFileNamePattern, fileName)) {
            LOGGER.warn("[{}] does not match the recommended pattern [{}]. "
                    + "While CAS tries to be forgiving as much as possible, it's recommended "

View on GitHub (pinned to e7288fc434)