{"record":{"id":"9458d138216efb5e","repo":"quarkusio/quarkus","slug":"failed-to-close-directory-stream-opened-for-certif","errorCode":null,"errorMessage":"Failed to close directory stream opened for certificate directory + certDir","messagePattern":"Failed to close directory stream opened for certificate directory \\+ certDir","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"extensions/tls-registry/runtime/src/main/java/io/quarkus/tls/runtime/config/PemCertsConfig.java","lineNumber":47,"sourceCode":"     * Any file in the configured directories will be treated as a trusted certificate in the Pem format.\n     */\n    Optional<List<Path>> certDirs();\n\n    default boolean hasNoTrustedCertificates() {\n        if (certs().isPresent() && !certs().get().isEmpty()) {\n            return false;\n        }\n\n        List<Path> certDirs = certDirs().orElse(null);\n        if (certDirs != null && !certDirs.isEmpty()) {\n            // whether any of certificate directories contains at least one file\n            for (Path certDir : certDirs) {\n                try (var ds = streamDirectory(certDir)) {\n                    if (ds.iterator().hasNext()) {\n                        return false;\n                    }\n                } catch (IOException e) {\n                    throw new RuntimeException(\"Failed to close directory stream opened for certificate directory \" + certDir,\n                            e);\n                }\n            }\n            var logger = Logger.getLogger(PemCertsConfig.class);\n            if (logger.isDebugEnabled()) {\n                logger.debugf(\"There is %d configured directories for the trusted certificates (%s), but \"\n                        + \"none of the directories contains any file\", certDirs.size(), certDirs);\n            }\n        }\n\n        return true;\n    }\n\n    default PemTrustOptions toOptions() {\n        PemTrustOptions options = new PemTrustOptions();\n\n        var certs = certs().orElse(null);\n        if (certs != null) {","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/tls-registry/runtime/src/main/java/io/quarkus/tls/runtime/config/PemCertsConfig.java#L29-L65","documentation":"While checking whether any trusted PEM certificate is configured, PemCertsConfig.hasNoTrustedCertificates opens a DirectoryStream per configured cert-dir; if closing the stream (the try-with-resources block) raises an IOException, it is rethrown wrapped in a RuntimeException claiming the stream 'failed to close'. Despite the message, this fires on close(), not on opening.","triggerScenarios":"An IOException thrown by DirectoryStream.close() while iterating certDirs configured via quarkus.tls.key-store/trust-store.pem.certDirs — typically on filesystems where closing a directory handle can fail (NFS stale handles, disks removed mid-scan).","commonSituations":"Cert directories on network mounts or removable media that disappear or become stale between open and close; container volumes being torn down during startup; underlying I/O errors surfaced at close time.","solutions":["Check the chained 'Caused by' IOException for the real filesystem problem","Verify the certDirs paths point to stable, healthy local directories","Move certificate directories onto local storage or a reliable volume","Ensure the directory is readable and not being mutated by another process during startup"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"for (Path dir : certDirs) {\n    if (!Files.isDirectory(dir)) throw new IllegalStateException(\"Invalid certDir: \" + dir);\n    try (var s = Files.list(dir)) { s.findAny(); }\n}\n","typeGuard":"static boolean isReadableDirectory(Path p) {\n    return p != null && Files.isDirectory(p) && Files.isReadable(p);\n}","tryCatchPattern":"try {\n    options = pemCertsConfig.toOptions();\n} catch (RuntimeException e) {\n    // inspect e.getCause() (IOException) for the real close-time failure\n    throw new RuntimeException(\"Trust cert dir scan failed: \" + e.getCause(), e);\n}","preventionTips":["Keep cert directories on local, reliable storage during startup","Avoid mutating cert directories while the app boots","Check 'Caused by' IOException for the real filesystem error","Pre-mount secrets before application startup in Kubernetes"],"tags":["quarkus","tls-registry","io","filesystem"],"backgroundTag":"directory-stream-io-error","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}