apereo/cas · critical · IllegalArgumentException
Metadata directory location cannot be located/created
Error message
Metadata directory location cannot be located/created
What it means
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.
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.
Example fix
// before cas.authn.samlIdp.metadata.git.repository-directory=/var/lib/cas/saml-git // not writable // after sudo mkdir -p /var/lib/cas/saml-git && sudo chown -R cas:cas /var/lib/cas/saml-git cas.authn.samlIdp.metadata.git.repository-directory=/var/lib/cas/saml-git
Defensive patterns
Strategy: validation
Validate before calling
// before using the git locator
File repo = new File(repositoryDirectory);
if (!repo.isDirectory() || !repo.canWrite())
throw new IllegalStateException("Git metadata repo missing or unwritable: " + repo); Try / catch
try {
File dir = locator.getMetadataDirectory(Optional.empty());
} catch (IllegalArgumentException e) {
logger.error("Metadata dir problem: {}", e.getMessage());
} Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Understand the failure class
Background: mkdir permission denied (EACCES): failed to create directory errors explained — this error's family across 32 libraries.
Related errors
- Metadata directory location cannot be located/created
- Metadata artifact at
- No assertion consumer service could be found for entity
- Endpoint for is not available or does not define a binding…
- Endpoint for does not define a binding or location for…
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/d1163e7c0b4149dc.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-saml-idp-metadata-git/src/main/java/org/apereo/cas/support/saml/idp/metadata/GitSamlIdPMetadataLocator.java:79
.encryptionCertificate(readFromFile(encryptionCert))
.encryptionKey(readFromFile(encryptionKey))
.signingCertificate(readFromFile(signingCert))
.signingKey(readFromFile(signingKey))
.metadata(readFromFile(metadataFile))
.build();
}
@Override
protected Resource getMetadataArtifact(final Optional<SamlRegisteredService> registeredService, final String artifactName) {
val file = getMetadataArtifactFile(registeredService, artifactName);
return new FileSystemResource(file);
}
private File getMetadataDirectory(final Optional<SamlRegisteredService> registeredService) {
val path = getAppliesToFor(registeredService);
val directory = new File(gitRepository.getRepositoryDirectory(), path);
if (!directory.exists() && registeredService.isEmpty() && !directory.mkdir()) {
throw new IllegalArgumentException("Metadata directory location " + directory + " cannot be located/created");
}
return directory;
}
private File getMetadataArtifactFile(final Optional<SamlRegisteredService> registeredService,
final String fileName) {
val defaultMetadataDirectory = getMetadataDirectory(Optional.empty());
val directory = getMetadataDirectory(registeredService);
val file = new File(directory, fileName);
if (file.exists() && file.canRead() && file.length() > 0) {
return file;
}
return new File(defaultMetadataDirectory, fileName);
}
private static String readFromFile(final File file) throws IOException {
return file.exists() && file.canRead() && file.length() > 0
? FileUtils.readFileToString(file, StandardCharsets.UTF_8)View on GitHub (pinned to e7288fc434)