apereo/cas · warning

Metadata artifact at

Error message

Metadata artifact at [{}] is empty and invalid and will be deleted

What it means

FileSystemSamlIdPMetadataLocator.getMetadataArtifact() reads the IdP metadata artifact file under the configured metadata location. If the file exists and is readable but its content is blank, it logs this warning, deletes the empty file, and returns the (now removed) file resource, forcing later resolution to regenerate or fail. It indicates corrupted/empty metadata storage.

Solutions

  1. Delete the empty artifact file and let CAS regenerate the metadata (the locator deletes it automatically; restart the flow)
  2. Restore the metadata file from backup or re-run metadata generation/upload
  3. Check disk space and I/O health to find why the write was truncated
  4. Verify the metadataLocation path and mounted volume point at the directory CAS actually wrote

Example fix

// before: manually recreating empty file
touch /etc/cas/saml/idp-metadata.json
// after: remove and regenerate
rm /etc/cas/saml/idp-metadata.json
# restart metadata generation flow in CAS
Defensive patterns

Strategy: fallback

Validate before calling

// precheck artifact content before resolution
val content = Files.readString(Path.of(metadataLocation, artifactName));
if (content.isBlank()) regenerateMetadata();

Type guard

function artifactValid(r) { return r != null && r.exists() && r.isReadable() && !readAll(r).isBlank(); }

Try / catch

try { resource = locator.getMetadataArtifact(service); }
catch (Exception e) { resource = regenerateOrDefault(service); }

Prevention

When it happens

Trigger: Calling resolveMetadata/resolveSigningKey/resolveEncryptionKey (or the locator directly) when the artifact file at {metadataLocation}/{artifactName} exists but contains zero bytes or only whitespace, e.g. after a crashed write or a truncating touch.

Common situations: Disk-full or crash during metadata generation leaving a 0-byte file; an admin running 'touch' on the metadata file; mounting an empty file in the metadata directory via Docker; storage cleanup jobs truncating files.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at support/cas-server-support-saml-idp-core/src/main/java/org/apereo/cas/support/saml/idp/metadata/locator/FileSystemSamlIdPMetadataLocator.java:129

                : new File(this.metadataLocation, getAppliesToFor(registeredService));
            LOGGER.debug("Metadata directory location for [{}] is [{}]", samlRegisteredService.getName(), serviceDirectory);
            if (serviceDirectory.exists()) {
                val artifact = new File(serviceDirectory, artifactName);
                LOGGER.trace("Artifact location for [{}] and [{}] is [{}]", artifactName, samlRegisteredService.getName(), artifact);
                if (artifact.exists()) {
                    LOGGER.debug("Using metadata artifact [{}] at [{}]", artifactName, artifact);
                    return ResourceUtils.toFileSystemResource(artifact);
                }
            }
        }
        initializeMetadataDirectory();
        val resource = ResourceUtils.toFileSystemResource(new File(this.metadataLocation, artifactName));
        if (resource.exists() && resource.isReadable()) {
            val content = FileUtils.readFileToString(resource.getFile(), StandardCharsets.UTF_8);
            if (StringUtils.isNotBlank(content)) {
                return resolveContentToResource(content);
            }
            LOGGER.warn("Metadata artifact at [{}] is empty and invalid and will be deleted", resource);
            FileUtils.deleteQuietly(resource.getFile());
        }
        return ResourceUtils.toFileSystemResource(resource.getFile());
    }

    protected void initializeMetadataDirectory() {
        if (!this.metadataLocation.exists()) {
            LOGGER.debug("Metadata directory [{}] does not exist. Creating...", this.metadataLocation);
            if (!this.metadataLocation.mkdir()) {
                throw new IllegalArgumentException("Metadata directory location " + this.metadataLocation + " cannot be located/created");
            }
        }
    }
}

View on GitHub (pinned to e7288fc434)