{"record":{"id":"cf441ad83700faad","repo":"elastic/elasticsearch","slug":"unknown-key-s-in-a-listed-file-for-files-ent","errorCode":null,"errorMessage":"unknown key(s) [{}] in a listed file for files entitlement","messagePattern":"unknown key\\(s\\) \\[(.+?)\\] in a listed file for files entitlement","errorType":"validation","errorClass":"PolicyValidationException","httpStatus":null,"severity":"error","filePath":"libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/entitlements/FilesEntitlement.java","lineNumber":249,"sourceCode":"                    + value.getClass().getSimpleName()\n                    + \"]\"\n            );\n        };\n        List<FileData> filesData = new ArrayList<>();\n        for (Object object : paths) {\n            Map<String, Object> file = new HashMap<>((Map<String, Object>) object);\n            String pathAsString = checkString.apply(file, \"path\");\n            String relativePathAsString = checkString.apply(file, \"relative_path\");\n            String relativeTo = checkString.apply(file, \"relative_to\");\n            String pathSetting = checkString.apply(file, \"path_setting\");\n            String settingBaseDirAsString = checkString.apply(file, \"basedir_if_relative\");\n            String modeAsString = checkString.apply(file, \"mode\");\n            String platformAsString = checkString.apply(file, \"platform\");\n            Boolean exclusiveBoolean = checkBoolean.apply(file, \"exclusive\");\n            boolean exclusive = exclusiveBoolean != null && exclusiveBoolean;\n\n            if (file.isEmpty() == false) {\n                throw new PolicyValidationException(\"unknown key(s) [\" + file + \"] in a listed file for files entitlement\");\n            }\n            int foundKeys = (pathAsString != null ? 1 : 0) + (relativePathAsString != null ? 1 : 0) + (pathSetting != null ? 1 : 0);\n            if (foundKeys != 1) {\n                throw new PolicyValidationException(\n                    \"a files entitlement entry must contain one of \" + \"[path, relative_path, path_setting]\"\n                );\n            }\n\n            if (modeAsString == null) {\n                throw new PolicyValidationException(\"files entitlement must contain 'mode' for every listed file\");\n            }\n            Mode mode = parseMode(modeAsString);\n            Platform platform = null;\n            if (platformAsString != null) {\n                platform = parsePlatform(platformAsString);\n            }\n\n            if (relativeTo != null && relativePathAsString == null) {","sourceCodeStart":231,"sourceCodeEnd":267,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/entitlements/FilesEntitlement.java#L231-L267","documentation":"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.","triggerScenarios":"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`.","commonSituations":"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.","solutions":["Read the message: it prints the leftover key map verbatim, naming the unknown keys.","Rename or remove each unknown key; map it to the closest recognised equivalent (e.g. `readonly:true` -> `mode: \"read\"`).","Validate the policy against the current schema before deploying."],"exampleFix":"// before\n{ \"dir\": \"/var/log/es\", \"access\": \"rw\" }\n\n// after\n{ \"path\": \"/var/log/es\", \"mode\": \"read_write\" }","handlingStrategy":"validation","validationCode":"private static final Set<String> ALLOWED_KEYS = Set.of(\n    \"path\",\"relative_path\",\"relative_to\",\"path_setting\",\"basedir_if_relative\",\"mode\",\"platform\",\"exclusive\");\npublic static void validateEntryKeys(Map<String,Object> entry) {\n    for (String k : entry.keySet()) {\n        if (!ALLOWED_KEYS.contains(k)) {\n            throw new IllegalArgumentException(\"unknown key in files entry: \" + k);\n        }\n    }\n}","typeGuard":"public static boolean hasOnlyAllowedKeys(Map<String,Object> entry) {\n    return ALLOWED_KEYS.containsAll(entry.keySet());\n}","tryCatchPattern":null,"preventionTips":["Lint policy files against a JSON Schema with additionalProperties:false.","Watch for misspellings introduced by autocomplete or copy-paste.","Treat the unknown-key message as authoritative — it prints the leftover map."],"tags":["entitlements","files","policy","validation","schema"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}