{"id":"46549d36900c1c25","repo":"apache/kafka","slug":"could-not-list-directory-dir","errorCode":null,"errorMessage":"Could not list directory {dir}","messagePattern":"Could not list directory (.+?)","errorType":"validation","errorClass":"ConfigException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/config/provider/DirectoryConfigProvider.java","lineNumber":111,"sourceCode":"        if (path != null && !path.isEmpty()) {\n            Path dir = allowedPaths.parseUntrustedPath(path);\n            if (dir == null) {\n                log.warn(\"The path {} is not allowed to be accessed\", path);\n                return new ConfigData(map);\n            }\n\n            if (!Files.isDirectory(dir)) {\n                log.warn(\"The path {} is not a directory\", path);\n            } else {\n                try (Stream<Path> stream = Files.list(dir)) {\n                    map = stream\n                        .filter(fileFilter)\n                        .collect(Collectors.toMap(\n                            p -> p.getFileName().toString(),\n                            p -> read(p)));\n                } catch (IOException e) {\n                    log.error(\"Could not list directory {}\", dir, e);\n                    throw new ConfigException(\"Could not list directory \" + dir);\n                }\n            }\n        }\n        return new ConfigData(map);\n    }\n\n    private static String read(Path path) {\n        try {\n            return Files.readString(path);\n        } catch (IOException e) {\n            log.error(\"Could not read file {} for property {}\", path, path.getFileName(), e);\n            throw new ConfigException(\"Could not read file \" + path + \" for property \" + path.getFileName());\n        }\n    }\n\n}\n","sourceCodeStart":93,"sourceCodeEnd":128,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/config/provider/DirectoryConfigProvider.java#L93-L128","documentation":"Thrown as ConfigException by DirectoryConfigProvider.get() when Files.list(dir) raises an IOException while streaming the contents of a directory that already passed the allowed-paths and isDirectory() checks. The exception is logged with full stack trace at ERROR and then rethrown without the cause so callers see a clean message naming the directory.","triggerScenarios":"DirectoryConfigProvider.get(path) where path resolves to a real, allowed directory, but listing it fails with IOException (e.g. FileSystemException, AccessDeniedException, ClosedFileSystemException). The listing occurs inside a try-with-resources on the Stream from Files.list.","commonSituations":"JVM loses read permission on the directory between the isDirectory check and the list call (race with chmod/chown). Network filesystem (NFS/CIFS) hiccup mid-listing. Container filesystem where the directory is a mount that gets unmounted concurrently. SELinux denial on readdir.","solutions":["Check the ERROR log line 'Could not list directory <dir>' which carries the underlying IOException stack trace for the real cause.","Confirm read+execute permissions for the JVM user on the directory: ls -ld <dir> && sudo -u <kafka-user> ls <dir>.","For container/network mounts, verify the mount is healthy and stable during provider access.","Review SELinux/AppManager audit logs and add allow rules for the Kafka process on the directory."],"exampleFix":"# before\nchmod 700 /etc/kafka/secrets   # kafka user cannot list\n\n# after\nchown kafka:kafka /etc/kafka/secrets\nchmod 750 /etc/kafka/secrets","handlingStrategy":"validation","validationCode":"// Pre-check directory accessibility before provider.get(path):\nPath dir = Paths.get(path);\nif (!Files.isDirectory(dir)) {\n    throw new IllegalArgumentException(path + \" is not a directory\");\n}\nif (!Files.isReadable(dir)) {\n    throw new IllegalArgumentException(path + \" is not readable\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    provider.get(path);\n} catch (ConfigException e) {\n    if (e.getMessage().startsWith(\"Could not list directory\")) {\n        // log dir, check perms, degrade to empty ConfigData, or rethrow as app error\n    } else { throw e; }\n}","preventionTips":["Verify directory exists, is a directory, and is readable by the JVM user before invoking the provider.","On POSIX systems ensure the execute (search) bit is set on the directory for the JVM's user/group.","Guard against TOCTOU: pre-checks reduce common cases but cannot eliminate races — keep the try/catch as a safety net."],"tags":["config-provider","filesystem","permissions","directory-config-provider"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}