apereo/cas · warning

Provided file [ ] does not match the recommended service…

Error message

Provided file [{}] does not match the recommended service definition file pattern [{}]

What it means

getRegisteredServiceFromFile parses a filename to find the service it contains (extracting id or name via the serviceFileNamePattern). When the filename does not match the pattern, no matcher groups exist, CAS logs this warning and returns null — the service cannot be resolved from that file.

Solutions

  1. Rename the file to the required '<numericId>-<serviceName>.json' format.
  2. Remove backup/editor/temp files from the services directory so they are never parsed.
  3. If the file is intentionally non-standard, move it outside the watched services directory.

Example fix

// before
/etc/cas/config/services/1001-app.json.bak   // triggers warning
// after
mv /etc/cas/config/services/1001-app.json.bak ~/backups/
Defensive patterns

Strategy: validation

Validate before calling

// Same guard as 395, applied before files reach the watched directory
if (!fileName.matches("\\d+-[^.]+\\.json")) {
    throw new IllegalArgumentException("Service file must be <id>-<name>.json");
}

Prevention

When it happens

Trigger: Watcher/reload paths calling getRegisteredServiceFromFile(file) on a file whose name (e.g. 'service-backup.json') doesn't match '<id>-<name>.<ext>'; pattern match produced no groups.

Common situations: Backup or temp files (e.g. '1001-app.json.bak~', editor swap files) in the services directory; files renamed while CAS watches the directory.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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

Appendix: source

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

        if (!fileName.isEmpty() && fileName.charAt(0) == '.') {
            LOGGER.trace("[{}] starts with ., ignoring...", fileName);
            return null;
        }
        if (Arrays.stream(getExtensions()).noneMatch(fileName::endsWith)) {
            LOGGER.trace("[{}] doesn't end with valid extension, ignoring", fileName);
            return null;
        }
        val matcher = this.serviceFileNamePattern.matcher(fileName);
        if (matcher.find()) {
            val serviceId = matcher.group(2);
            if (NumberUtils.isCreatable(serviceId)) {
                val id = Long.parseLong(serviceId);
                return findServiceById(id);
            }
            val serviceName = matcher.group(1);
            return findServiceByExactServiceName(serviceName);
        }
        LOGGER.warn("Provided file [{}] does not match the recommended service definition file pattern [{}]",
            file.getName(),
            this.serviceFileNamePattern.pattern());
        return null;
    }

    protected File getRegisteredServiceFileName(final RegisteredService service) {
        val fileName = resourceNamingStrategy.build(service, getExtensions()[0]);

        val parentDirectory = determineParentDirectoryFor(service);
        val svcFile = new File(parentDirectory, fileName);
        LOGGER.debug("Using [{}] as the service definition file", svcFile.getAbsolutePath());
        return svcFile;
    }

    private File determineParentDirectoryFor(final RegisteredService service) {
        val defaultServicesDirectory = serviceRegistryDirectory.toFile();

        val friendlyName = service.getFriendlyName();

View on GitHub (pinned to e7288fc434)