apereo/cas · warning

Input stream from resource

Error message

Input stream from resource [{}] appears empty. Moving on...

What it means

While building the MDUI metadata aggregate, the input stream for a metadata resource reported zero available bytes. CAS logs this warning and skips the resource, returning an empty list for that resolver contribution.

Solutions

  1. Verify the metadata resource file exists and is non-empty (ls -l / curl -I).
  2. Re-download or re-sync the metadata source.
  3. If the resource is remote and streams lazily, prefer a cached/downloaded local copy instead of relying on available().
  4. Check the preceding exception-free path: no other error means genuinely empty content.

Example fix

// before: pointing at empty file
metadata-reference: file:/etc/cas/mdui/empty.xml
// after
metadata-reference: file:/etc/cas/mdui/valid-metadata.xml
Defensive patterns

Strategy: validation

Validate before calling

var res = applicationContext.getResource(path);
if (!res.exists() || res.contentLength() == 0) {
    LOGGER.warn("Metadata resource empty: {}", path);
    return List.of();
}

Prevention

When it happens

Trigger: loadMetadataFromResource opens the resource's stream and in.available() == 0 — an empty metadata file, a truncated download, or a stream that has no buffered bytes yet (some remote resources legitimately report 0 available without being empty).

Common situations: Empty or partially written metadata XML on disk; HTTP resource returning empty body; network resource whose available() semantics mislead; race while metadata file is regenerated.

Related errors


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

Appendix: source

Thrown at support/cas-server-support-saml-mdui-core/src/main/java/org/apereo/cas/support/saml/mdui/AbstractMetadataResolverAdapter.java:117

    protected InputStream getResourceInputStream(final Resource resource, final String entityId) throws IOException {
        LOGGER.debug("Locating metadata resource from input stream.");
        if (!resource.exists() || !resource.isReadable()) {
            throw new FileNotFoundException("Resource does not exist or is unreadable");
        }
        return resource.getInputStream();
    }

    private List<MetadataResolver> loadMetadataFromResource(final MetadataFilter metadataFilter, final Resource resource,
                                                            final String entityId) {
        LOGGER.debug("Evaluating metadata resource [{}]", resource.getFilename());
        try (val in = getResourceInputStream(resource, entityId)) {
            if (in.available() > 0) {
                LOGGER.debug("Parsing [{}]", resource.getFilename());
                val document = this.configBean.getParserPool().parse(in);
                return buildSingleMetadataResolver(metadataFilter, resource, document);
            }
            LOGGER.warn("Input stream from resource [{}] appears empty. Moving on...", resource.getFilename());
        } catch (final Exception e) {
            LoggingUtils.warn(LOGGER, "Could not retrieve input stream from resource. Moving on...", e);
        }
        return new ArrayList<>();
    }

    /**
     * Build single metadata resolver.
     *
     * @param metadataFilterChain the metadata filters chained together
     * @param resource            the resource
     * @param document            the xml document to parse
     * @return list of resolved metadata from resources.
     */
    private List<MetadataResolver> buildSingleMetadataResolver(final MetadataFilter metadataFilterChain, final Resource resource,
                                                               final Document document) {
        val metadataRoot = document.getDocumentElement();
        val metadataProvider = new DOMMetadataResolver(metadataRoot);

View on GitHub (pinned to e7288fc434)