{"id":"90b92c47e3064fd6","repo":"apache/kafka","slug":"path-normalisedpath-does-not-exist","errorCode":null,"errorMessage":"Path normalisedPath does not exist","messagePattern":"Path normalisedPath does not exist","errorType":"validation","errorClass":"ConfigException","httpStatus":null,"severity":"error","filePath":"clients/src/main/java/org/apache/kafka/common/config/internals/AllowedPaths.java","lineNumber":51,"sourceCode":"     * Constructs AllowedPaths with a list of Paths retrieved from {@code configValue}.\n     * @param configValue {@code allowed.paths} config value which is a string containing comma separated list of paths\n     * @throws ConfigException if any of the given paths is not absolute or does not exist.\n     */\n    public AllowedPaths(String configValue) {\n        this.allowedPaths = getAllowedPaths(configValue);\n    }\n\n    private List<Path> getAllowedPaths(String configValue) {\n        if (configValue != null && !configValue.isEmpty()) {\n            List<Path> allowedPaths = new ArrayList<>();\n\n            Arrays.stream(configValue.split(\",\")).forEach(b -> {\n                Path normalisedPath = Paths.get(b).normalize();\n\n                if (!normalisedPath.isAbsolute()) {\n                    throw new ConfigException(\"Path \" + normalisedPath + \" is not absolute\");\n                } else if (!Files.exists(normalisedPath)) {\n                    throw new ConfigException(\"Path \" + normalisedPath + \" does not exist\");\n                } else {\n                    try {\n                        allowedPaths.add(normalisedPath.toRealPath());\n                    } catch (IOException e) {\n                        throw new ConfigException(\"Path \" + normalisedPath + \" could not be resolved\", e);\n                    }\n                }\n            });\n\n            return allowedPaths;\n        }\n\n        return null;\n    }\n\n    /**\n     * Checks if the given {@code path} resides in the configured {@code allowed.paths}.\n     * If {@code allowed.paths} is not configured, the given Path is returned as allowed.","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/apache/kafka/blob/c31c9215e131f8c17e79f8901b48c13ee6aa8e7a/clients/src/main/java/org/apache/kafka/common/config/internals/AllowedPaths.java#L33-L69","documentation":"Thrown by AllowedPaths.getAllowedPaths() when a configured allowed.paths entry passes the isAbsolute() check but does not exist on the filesystem (Files.exists returns false). The check happens at provider configure() time so missing directories are caught before any externalized config lookup is attempted.","triggerScenarios":"Constructing AllowedPaths / configuring DirectoryConfigProvider or FileConfigProvider with an absolute path that does not exist on the host (typo, wrong host, not yet mounted).","commonSituations":"Secrets directory not mounted yet in a container (Kubernetes volumeMount not ready). Typo in an absolute path. Deploying a config referencing a path that exists in staging but not in production. Wrong user/namespace so the mount path differs.","solutions":["Verify the path exists on the host/container with ls -ld <path>.","Fix typos or correct the host-specific absolute path in allowed.paths.","If using containers, confirm the volume/mount is present and the entrypoint runs after mounts are ready.","Create the directory (mkdir -p) if it is legitimately absent but expected."],"exampleFix":"# before\nallowed.paths=/etc/kafka/secrets  # path missing\n\n# after\nmkdir -p /etc/kafka/secrets\nallowed.paths=/etc/kafka/secrets","handlingStrategy":"validation","validationCode":"// Probe existence before AllowedPaths construction:\nfor (String raw : configValue.split(\",\")) {\n    Path p = Paths.get(raw.trim()).normalize();\n    if (!Files.exists(p)) {\n        throw new IllegalArgumentException(\n            \"allowed.paths entry '\" + p + \"' does not exist\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    AllowedPaths ap = new AllowedPaths(configValue);\n} catch (ConfigException e) {\n    if (e.getMessage().endsWith(\"does not exist\")) {\n        // log, create the dir/file, or degrade gracefully\n    } else { throw e; }\n}","preventionTips":["Create required directories/secrets-mount paths during deployment before the broker/client reads allowed.paths.","For containerized workloads, mount the config volume and assert its existence in an entrypoint preflight before exec'ing the JVM.","Treat a missing allowed.paths entry as a deploy-time defect: fail the healthcheck rather than silently allowing all paths."],"tags":["config","allowed-paths","filesystem","config-provider"],"analyzedSha":"c31c9215e131f8c17e79f8901b48c13ee6aa8e7a","analyzedAt":"2026-08-03T12:34:05.770Z","schemaVersion":2}