elastic/elasticsearch · error · PolicyValidationException

a files entitlement entry must contain one of [path, relativ

Error message

a files entitlement entry must contain one of [path, relative_path, path_setting]

What it means

Thrown when none (or more than one) of the mutually-exclusive path-designator keys path / relative_path / path_setting is set on a files-entitlement entry. The parser counts non-null occurrences among the three and requires exactly one so each entry resolves to an unambiguous target.

Source

Thrown at libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/entitlements/FilesEntitlement.java:253

        List<FileData> filesData = new ArrayList<>();
        for (Object object : paths) {
            Map<String, Object> file = new HashMap<>((Map<String, Object>) object);
            String pathAsString = checkString.apply(file, "path");
            String relativePathAsString = checkString.apply(file, "relative_path");
            String relativeTo = checkString.apply(file, "relative_to");
            String pathSetting = checkString.apply(file, "path_setting");
            String settingBaseDirAsString = checkString.apply(file, "basedir_if_relative");
            String modeAsString = checkString.apply(file, "mode");
            String platformAsString = checkString.apply(file, "platform");
            Boolean exclusiveBoolean = checkBoolean.apply(file, "exclusive");
            boolean exclusive = exclusiveBoolean != null && exclusiveBoolean;

            if (file.isEmpty() == false) {
                throw new PolicyValidationException("unknown key(s) [" + file + "] in a listed file for files entitlement");
            }
            int foundKeys = (pathAsString != null ? 1 : 0) + (relativePathAsString != null ? 1 : 0) + (pathSetting != null ? 1 : 0);
            if (foundKeys != 1) {
                throw new PolicyValidationException(
                    "a files entitlement entry must contain one of " + "[path, relative_path, path_setting]"
                );
            }

            if (modeAsString == null) {
                throw new PolicyValidationException("files entitlement must contain 'mode' for every listed file");
            }
            Mode mode = parseMode(modeAsString);
            Platform platform = null;
            if (platformAsString != null) {
                platform = parsePlatform(platformAsString);
            }

            if (relativeTo != null && relativePathAsString == null) {
                throw new PolicyValidationException("'relative_to' may only be used with 'relative_path'");
            }

            if (settingBaseDirAsString != null && pathSetting == null) {

View on GitHub (pinned to db6a809a66)

Solutions

  1. Provide exactly one of: `path` (absolute), `relative_path` (paired with `relative_to`), or `path_setting` (paired with `basedir_if_relative`).
  2. If two are present, decide which one you meant and delete the other.
  3. If none is present, add the one matching your intent.

Example fix

// before
{ "mode": "read", "path": "/x", "relative_path": "logs" }

// after
{ "mode": "read", "relative_path": "logs", "relative_to": "home" }
Defensive patterns

Strategy: validation

Validate before calling

public static void validateExactlyOnePathDesignator(Map<String,Object> entry) {
    int n = 0;
    for (String k : List.of("path","relative_path","path_setting")) if (entry.containsKey(k)) n++;
    if (n != 1) {
        throw new IllegalArgumentException("entry must contain exactly one of path/relative_path/path_setting, got " + n);
    }
}

Type guard

public static boolean hasExactlyOnePathDesignator(Map<String,Object> entry) {
    int n = 0;
    if (entry.containsKey("path")) n++;
    if (entry.containsKey("relative_path")) n++;
    if (entry.containsKey("path_setting")) n++;
    return n == 1;
}

Prevention

When it happens

Trigger: An entry omits all three path keys (e.g. only `mode` is provided), or supplies more than one (e.g. both `path` and `relative_path`). The foundKeys counter will be 0 or 2+ respectively.

Common situations: Forgetting the path designator entirely; providing both `path` and `relative_path` thinking they compose; templating bug that conditionally drops the path; misunderstanding that exactly one is required.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/11d1adf28ad2959e. Report an issue: GitHub.