apache/kafka · error · ConfigException

Path normalisedPath is not absolute

Error message

Path normalisedPath is not absolute

What it means

Thrown by AllowedPaths.getAllowedPaths() when parsing a comma-separated allowed.paths config value containing a relative path. The code calls Paths.get(b).normalize() then checks isAbsolute(); a non-absolute path is rejected with ConfigException. Kafka enforces absolute paths so that DirectoryConfigProvider/FileConfigProvider can safely resolve real paths and prevent traversal attacks.

Source

Thrown at clients/src/main/java/org/apache/kafka/common/config/internals/AllowedPaths.java:49

    /**
     * Constructs AllowedPaths with a list of Paths retrieved from {@code configValue}.
     * @param configValue {@code allowed.paths} config value which is a string containing comma separated list of paths
     * @throws ConfigException if any of the given paths is not absolute or does not exist.
     */
    public AllowedPaths(String configValue) {
        this.allowedPaths = getAllowedPaths(configValue);
    }

    private List<Path> getAllowedPaths(String configValue) {
        if (configValue != null && !configValue.isEmpty()) {
            List<Path> allowedPaths = new ArrayList<>();

            Arrays.stream(configValue.split(",")).forEach(b -> {
                Path normalisedPath = Paths.get(b).normalize();

                if (!normalisedPath.isAbsolute()) {
                    throw new ConfigException("Path " + normalisedPath + " is not absolute");
                } else if (!Files.exists(normalisedPath)) {
                    throw new ConfigException("Path " + normalisedPath + " does not exist");
                } else {
                    try {
                        allowedPaths.add(normalisedPath.toRealPath());
                    } catch (IOException e) {
                        throw new ConfigException("Path " + normalisedPath + " could not be resolved", e);
                    }
                }
            });

            return allowedPaths;
        }

        return null;
    }

    /**

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Change every entry in allowed.paths to an absolute path (e.g. /etc/kafka/secrets) and restart the client/broker.
  2. Verify with Paths.get(value).isAbsolute() in a test or REPL before deploying.
  3. Remove the offending entry from allowed.paths or unset the property entirely to allow all paths (only if your security posture permits).

Example fix

// before
allowed.paths=config/secrets,../shared/secrets

// after
allowed.paths=/etc/kafka/secrets,/opt/kafka/shared/secrets
Defensive patterns

Strategy: validation

Validate before calling

// Before constructing AllowedPaths or setting allowed.paths:
for (String raw : configValue.split(",")) {
    Path p = Paths.get(raw.trim()).normalize();
    if (!p.isAbsolute()) {
        throw new IllegalArgumentException(
            "allowed.paths entry '" + raw + "' must be absolute, got " + p);
    }
}

Try / catch

try {
    AllowedPaths ap = new AllowedPaths(configValue);
} catch (ConfigException e) {
    if (e.getMessage().endsWith("is not absolute")) {
        // resolve against a known base dir, or fail config load
    } else { throw e; }
}

Prevention

When it happens

Trigger: Constructing new AllowedPaths(configValue) (called from DirectoryConfigProvider.configure or FileConfigProvider.configure) with allowed.paths containing a relative path like "config/secrets" instead of "/etc/kafka/secrets".

Common situations: Running a connector or client that uses externalized config providers (DirectoryConfigProvider/FileConfigProvider) and supplying allowed.paths with a relative path. Porting a config from a dev environment where the working directory was implied. Mixing Windows-style or tilde-prefixed paths (~) which are not absolute to Paths.get.

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/4d628fa377476957.json. Report an issue: GitHub.