{"record":{"id":"27c1e7e70deeee06","repo":"apereo/cas","slug":"is-not-readable-check-file-permissions","errorCode":null,"errorMessage":"[{}] is not readable. Check file permissions","messagePattern":"\\[(.+?)\\] is not readable\\. Check file permissions","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/cas-server-core-services-registry/src/main/java/org/apereo/cas/services/resource/AbstractResourceBasedServiceRegistry.java","lineNumber":267,"sourceCode":"                .filter(service -> StringUtils.isNotBlank(service.getServiceId()) && StringUtils.isNotBlank(service.getName()))\n                .sorted()\n                .collect(Collectors.toMap(RegisteredService::getId, Function.identity(),\n                    (s1, s2) -> {\n                        BaseResourceBasedRegisteredServiceWatcher.LOG_SERVICE_DUPLICATE.accept(s2);\n                        return s1;\n                    }, LinkedHashMap::new));\n            val listedServices = new ArrayList<>(this.services.values());\n            val results = registeredServiceReplicationStrategy.updateLoadedRegisteredServicesFromCache(listedServices, this);\n            results.forEach(service -> publishEvent(new CasRegisteredServiceLoadedEvent(this, service, clientInfo)));\n            return results;\n        });\n    }\n\n    @Override\n    public Collection<RegisteredService> load(final File file) {\n        val fileName = file.getName();\n        if (!file.canRead()) {\n            LOGGER.warn(\"[{}] is not readable. Check file permissions\", fileName);\n            return new ArrayList<>();\n        }\n        if (!file.exists()) {\n            LOGGER.warn(\"[{}] is not found at the path specified\", fileName);\n            return new ArrayList<>();\n        }\n        if (file.length() == 0) {\n            LOGGER.debug(\"[{}] appears to be empty so no service definition will be loaded\", fileName);\n            return new ArrayList<>();\n        }\n        if (!fileName.isEmpty() && fileName.charAt(0) == '.') {\n            LOGGER.debug(\"[{}] starts with ., ignoring\", fileName);\n            return new ArrayList<>();\n        }\n        if (Arrays.stream(getExtensions()).noneMatch(fileName::endsWith)) {\n            LOGGER.debug(\"[{}] doesn't end with valid extension, ignoring\", fileName);\n            return new ArrayList<>();\n        }","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/core/cas-server-core-services-registry/src/main/java/org/apereo/cas/services/resource/AbstractResourceBasedServiceRegistry.java#L249-L285","documentation":"During load(File), AbstractResourceBasedServiceRegistry checks file.canRead() before parsing. If the file is unreadable due to OS permissions, it logs this warning and returns an empty collection — the service definition is silently not loaded.","triggerScenarios":"Calling serviceRegistry.load(file) (directly or via directory scan/watcher) on a file the CAS process cannot read, e.g. permission bits excluding the runtime user.","commonSituations":"Service JSON files copied in as root with 0600 permissions; container user mismatch after volume mount; SELinux/AppArmor denials.","solutions":["Fix file permissions so the CAS process user can read the file (chmod/chown).","Ensure files copied or mounted into the services directory are readable by all needed users (e.g. 0644).","Check SELinux/AppAudit policies if permissions look correct but access is still denied."],"exampleFix":"// before\n-rw------- root root 1000001-example.json\n// after\nchown cas:cas 1000001-example.json && chmod 644 1000001-example.json","handlingStrategy":"validation","validationCode":"File f = new File(path);\nif (!f.canRead()) {\n    throw new IllegalStateException(\"File not readable by CAS user: \" + f.getAbsolutePath());\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Deploy service files with 0644 permissions owned by the CAS user.","After volume mounts or file copies, verify readability as the runtime user (sudo -u cas cat file).","Check SELinux/AppArmor when POSIX permissions look correct."],"tags":["filesystem","permissions","service-registry"],"backgroundTag":"file-read-failed","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"}