{"record":{"id":"c81be24cbf8f1b91","repo":"apereo/cas","slug":"resource-does-not-exist-or-is-unreadable-c81be2","errorCode":null,"errorMessage":"Resource does not exist or is unreadable","messagePattern":"Resource does not exist or is unreadable","errorType":"exception","errorClass":"FileNotFoundException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-saml-mdui-core/src/main/java/org/apereo/cas/support/saml/mdui/AbstractMetadataResolverAdapter.java","lineNumber":103,"sourceCode":"        val resolvers = new ArrayList<MetadataResolver>(entries.size());\n        entries.forEach(entry -> {\n            val resource = entry.getKey();\n            LOGGER.debug(\"Loading [{}]\", resource.getFilename());\n            resolvers.addAll(loadMetadataFromResource(entry.getValue(), resource, entityId));\n        });\n        FunctionUtils.doUnchecked(_ -> {\n            this.metadataResolver.setId(ChainingMetadataResolver.class.getCanonicalName());\n            this.metadataResolver.setResolvers(resolvers);\n            LOGGER.debug(\"Collected metadata from [{}] resolvers(s). Initializing aggregate resolver...\", resolvers.size());\n            this.metadataResolver.initialize();\n            LOGGER.info(\"Metadata aggregate initialized successfully.\");\n        });\n    }\n\n    protected InputStream getResourceInputStream(final Resource resource, final String entityId) throws IOException {\n        LOGGER.debug(\"Locating metadata resource from input stream.\");\n        if (!resource.exists() || !resource.isReadable()) {\n            throw new FileNotFoundException(\"Resource does not exist or is unreadable\");\n        }\n        return resource.getInputStream();\n    }\n\n    private List<MetadataResolver> loadMetadataFromResource(final MetadataFilter metadataFilter, final Resource resource,\n                                                            final String entityId) {\n        LOGGER.debug(\"Evaluating metadata resource [{}]\", resource.getFilename());\n        try (val in = getResourceInputStream(resource, entityId)) {\n            if (in.available() > 0) {\n                LOGGER.debug(\"Parsing [{}]\", resource.getFilename());\n                val document = this.configBean.getParserPool().parse(in);\n                return buildSingleMetadataResolver(metadataFilter, resource, document);\n            }\n            LOGGER.warn(\"Input stream from resource [{}] appears empty. Moving on...\", resource.getFilename());\n        } catch (final Exception e) {\n            LoggingUtils.warn(LOGGER, \"Could not retrieve input stream from resource. Moving on...\", e);\n        }\n        return new ArrayList<>();","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-saml-mdui-core/src/main/java/org/apereo/cas/support/saml/mdui/AbstractMetadataResolverAdapter.java#L85-L121","documentation":"AbstractMetadataResolverAdapter.getResourceInputStream opens the configured SAML metadata Resource for parsing. If resource.exists() or resource.isReadable() fails, it throws a FileNotFoundException with this message before loadMetadataFromResource can build a resolver. It means the metadata file/URL is missing, wrong, or not readable by the CAS process.","triggerScenarios":"loadMetadataFromResource -> getResourceInputStream whenever the configured metadata Resource (file path, classpath entry, or URL) does not exist, was deleted/moved, or the OS/file permissions prevent reading.","commonSituations":"Typo'd metadata location in the SamlRegisteredService or samlIdp properties; file exists but CAS runs as a user without read permission; classpath resource not packaged; remote metadata URL unreachable in a way Spring Resource reports as nonexistent; container image without the metadata file mounted.","solutions":["Check the configured metadata resource path/URL for typos and confirm the file exists at that exact location","Fix filesystem permissions so the CAS process user can read the file","If it's a classpath resource, ensure the metadata file is packaged inside the overlay at that path","For remote URLs, verify reachability and that the HTTP fetch produces a readable stream","Restart/redeploy after restoring the metadata file; then reload the metadata resolver"],"exampleFix":"// before\ncas.authn.saml-idp.metadata.location=file:/etc/cas/saml/idp-metadata.xml   // file missing\n// after: place file and grant read access\ncp idp-metadata.xml /etc/cas/saml/ && chmod 644 /etc/cas/saml/idp-metadata.xml","handlingStrategy":"validation","validationCode":"// check the metadata resource before handing it to the resolver adapter\nResource res = resourceLoader.getResource(metadataLocation);\nif (!res.exists()) throw new IllegalStateException(\"Metadata resource missing: \" + metadataLocation);\nif (!res.isReadable()) throw new IllegalStateException(\"Metadata resource unreadable: \" + metadataLocation);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify metadata file paths/URLs in configuration at deploy time (fail fast health check)","Mount metadata files into containers and set correct ownership for the CAS user","Use classpath: resources carefully and confirm they are packaged in the WAR","Monitor metadata resource availability with a startup probe"],"tags":["saml","metadata","file-not-found","filesystem"],"backgroundTag":"file-not-found","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"}