{"record":{"id":"d1163e7c0b4149dc","repo":"apereo/cas","slug":"metadata-directory-location-cannot-be-located-cre-d1163e","errorCode":null,"errorMessage":"Metadata directory location  cannot be located/created","messagePattern":"Metadata directory location  cannot be located/created","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"critical","filePath":"support/cas-server-support-saml-idp-metadata-git/src/main/java/org/apereo/cas/support/saml/idp/metadata/GitSamlIdPMetadataLocator.java","lineNumber":79,"sourceCode":"            .encryptionCertificate(readFromFile(encryptionCert))\n            .encryptionKey(readFromFile(encryptionKey))\n            .signingCertificate(readFromFile(signingCert))\n            .signingKey(readFromFile(signingKey))\n            .metadata(readFromFile(metadataFile))\n            .build();\n    }\n\n    @Override\n    protected Resource getMetadataArtifact(final Optional<SamlRegisteredService> registeredService, final String artifactName) {\n        val file = getMetadataArtifactFile(registeredService, artifactName);\n        return new FileSystemResource(file);\n    }\n\n    private File getMetadataDirectory(final Optional<SamlRegisteredService> registeredService) {\n        val path = getAppliesToFor(registeredService);\n        val directory = new File(gitRepository.getRepositoryDirectory(), path);\n        if (!directory.exists() && registeredService.isEmpty() && !directory.mkdir()) {\n            throw new IllegalArgumentException(\"Metadata directory location \" + directory + \" cannot be located/created\");\n        }\n        return directory;\n    }\n\n    private File getMetadataArtifactFile(final Optional<SamlRegisteredService> registeredService,\n                                         final String fileName) {\n        val defaultMetadataDirectory = getMetadataDirectory(Optional.empty());\n        val directory = getMetadataDirectory(registeredService);\n        val file = new File(directory, fileName);\n        if (file.exists() && file.canRead() && file.length() > 0) {\n            return file;\n        }\n        return new File(defaultMetadataDirectory, fileName);\n    }\n\n    private static String readFromFile(final File file) throws IOException {\n        return file.exists() && file.canRead() && file.length() > 0\n            ? FileUtils.readFileToString(file, StandardCharsets.UTF_8)","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-saml-idp-metadata-git/src/main/java/org/apereo/cas/support/saml/idp/metadata/GitSamlIdPMetadataLocator.java#L61-L97","documentation":"GitSamlIdPMetadataLocator.getMetadataDirectory() computes the per-service metadata directory under the git repository working directory. When no registered service is given (default metadata path) and the directory does not exist yet, it attempts mkdir(); on failure it throws IllegalArgumentException that the metadata directory cannot be located or created.","triggerScenarios":"Called by defaultMetadataDirectory()/directory() with registeredService empty; the computed path (repository directory + appliesTo path) does not exist and File.mkdir() returns false (missing parents, permissions, or path is a file).","commonSituations":"Git metadata repository cloned into a read-only location; parent directories for the service path don't exist; CAS runs as a user that can't write the repository working dir; git repo directory configured incorrectly.","solutions":["Ensure the git repository directory (cas.authn.samlIdp.metadata.git.repository-directory) exists and is writable by the CAS process user.","Pre-create the expected subdirectory path, including parents (mkdir -p).","Verify the repository was cloned successfully and the working tree is present (not a bare repo path).","Check that nothing at the target path is a regular file blocking directory creation."],"exampleFix":"// before\ncas.authn.samlIdp.metadata.git.repository-directory=/var/lib/cas/saml-git   // not writable\n\n// after\nsudo mkdir -p /var/lib/cas/saml-git && sudo chown -R cas:cas /var/lib/cas/saml-git\ncas.authn.samlIdp.metadata.git.repository-directory=/var/lib/cas/saml-git","handlingStrategy":"validation","validationCode":"// before using the git locator\nFile repo = new File(repositoryDirectory);\nif (!repo.isDirectory() || !repo.canWrite())\n    throw new IllegalStateException(\"Git metadata repo missing or unwritable: \" + repo);","typeGuard":null,"tryCatchPattern":"try {\n    File dir = locator.getMetadataDirectory(Optional.empty());\n} catch (IllegalArgumentException e) {\n    logger.error(\"Metadata dir problem: {}\", e.getMessage());\n}","preventionTips":["Clone the metadata repo into a location writable by the CAS user.","Ensure a non-bare working tree exists at repository-directory.","Provision parent directories for per-service paths in deployment tooling."],"tags":["saml","idp","git","metadata","filesystem"],"backgroundTag":"mkdir-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"}