elastic/elasticsearch · error · PolicyValidationException

unknown key(s) [{}] in a listed file for files entitlement

Error message

unknown key(s) [{}] in a listed file for files entitlement

What it means

Thrown after FilesEntitlement.build has consumed all known keys from the entry map (path, relative_path, relative_to, path_setting, basedir_if_relative, mode, platform, exclusive). If the map still has leftover keys, those are unrecognised and the policy is rejected to surface typos and stale field names rather than silently ignoring them.

Source

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

                    + value.getClass().getSimpleName()
                    + "]"
            );
        };
        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) {

View on GitHub (pinned to db6a809a66)

Solutions

  1. Read the message: it prints the leftover key map verbatim, naming the unknown keys.
  2. Rename or remove each unknown key; map it to the closest recognised equivalent (e.g. `readonly:true` -> `mode: "read"`).
  3. Validate the policy against the current schema before deploying.

Example fix

// before
{ "dir": "/var/log/es", "access": "rw" }

// after
{ "path": "/var/log/es", "mode": "read_write" }
Defensive patterns

Strategy: validation

Validate before calling

private static final Set<String> ALLOWED_KEYS = Set.of(
    "path","relative_path","relative_to","path_setting","basedir_if_relative","mode","platform","exclusive");
public static void validateEntryKeys(Map<String,Object> entry) {
    for (String k : entry.keySet()) {
        if (!ALLOWED_KEYS.contains(k)) {
            throw new IllegalArgumentException("unknown key in files entry: " + k);
        }
    }
}

Type guard

public static boolean hasOnlyAllowedKeys(Map<String,Object> entry) {
    return ALLOWED_KEYS.containsAll(entry.keySet());
}

Prevention

When it happens

Trigger: A files-entitlement entry contains any key other than the eight recognised ones, e.g. `dir`, `target`, `access`, `recursive`, `readonly`, or a misspelling like `relativ_path`.

Common situations: Misspelling a field; using a field name from a different entitlement schema or older/newer version; copy-paste from documentation that uses an alias the parser does not accept; trailing scaffold keys from templating.

Related errors


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