{"record":{"id":"30f26b5e7a4eb62d","repo":"apereo/cas","slug":"configuration-file-is-not-readable-writable-o","errorCode":null,"errorMessage":"Configuration file [{}] is not readable/writable or is not a path to a file","messagePattern":"Configuration file \\[(.+?)\\] is not readable/writable or is not a path to a file","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"support/cas-server-support-shell-core/src/main/java/org/apereo/cas/shell/commands/properties/AddPropertiesToConfigurationCommand.java","lineNumber":56,"sourceCode":"            defaultValue = \"/etc/cas/config/cas.properties\"\n        )\n        final String file,\n\n        @Option(\n            longName = \"group\",\n            description = \"Group/module whose associated settings should be added to the CAS configuration file\"\n        )\n        final String group\n    ) throws Exception {\n\n        if (StringUtils.isBlank(file)) {\n            LOGGER.warn(\"Configuration file must be specified\");\n            return;\n        }\n\n        val filePath = new File(file);\n        if (filePath.exists() && (filePath.isDirectory() || !filePath.canRead() || !filePath.canWrite())) {\n            LOGGER.warn(\"Configuration file [{}] is not readable/writable or is not a path to a file\", filePath.getCanonicalPath());\n            return;\n        }\n\n        val results = findProperties(group);\n        LOGGER.info(\"Located [{}] properties matching [{}]\", results.size(), group);\n\n        switch (FilenameUtils.getExtension(filePath.getName()).toLowerCase(Locale.ENGLISH)) {\n            case \"properties\" -> {\n                createConfigurationFileIfNeeded(filePath);\n                val props = loadPropertiesFromConfigurationFile(filePath);\n                writeConfigurationPropertiesToFile(filePath, results, props);\n            }\n            case \"yaml\", \"yml\" -> {\n                createConfigurationFileIfNeeded(filePath);\n                val yamlProps = CasCoreConfigurationUtils.loadYamlProperties(new FileSystemResource(filePath));\n                writeYamlConfigurationPropertiesToFile(filePath, results, yamlProps);\n            }\n            default -> LOGGER.warn(\"Configuration file format [{}] is not recognized\", filePath.getCanonicalPath());","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-shell-core/src/main/java/org/apereo/cas/shell/commands/properties/AddPropertiesToConfigurationCommand.java#L38-L74","documentation":"AddPropertiesToConfigurationCommand.add() refuses to modify a configuration file if the path exists but is a directory or is not readable and writable. This guard protects the Spring Cloud config property-editing shell command from writing to a target it cannot safely read-modify-write. The command logs a warning and aborts without adding any properties.","triggerScenarios":"Running 'cas add-properties-to-configuration --file <path>' where the file path exists but is a directory, or exists with OS permissions denying read or write access to the current user.","commonSituations":"Pointing --file at a directory instead of the application.properties/yml file; running the CAS shell as a user lacking write permission on the config file (e.g. file owned by root or a service account); file mounted read-only in a container.","solutions":["Pass the full path to the actual configuration file (application.properties or application.yml), not its parent directory","Fix filesystem permissions so the shell user can both read and write the file (chmod/chown)","Check that the path is not a read-only mount (container volume, mounted disk)","If the file does not exist yet, the command creates it; ensure the parent directory is writable"],"exampleFix":"// before\ncas add-properties-to-configuration --file /etc/cas/config --group cas.server --name port --value 8443\n// after\ncas add-properties-to-configuration --file /etc/cas/config/application.properties --group cas.server --name port --value 8443","handlingStrategy":"validation","validationCode":"File f = new File(path);\nif (f.exists() && (f.isDirectory() || !f.canRead() || !f.canWrite())) {\n    throw new IllegalArgumentException(\"Config path must be a readable/writable file: \" + path);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass the concrete config file path, never a directory","Run the shell command as a user with read/write access to the config directory","Check for read-only mounts before scripted config edits"],"tags":["filesystem","permissions","configuration","cli"],"backgroundTag":"file-write-permission-denied","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"}