elastic/elasticsearch · error · PolicyValidationException
must specify at least one path
Error message
must specify at least one path
What it means
Thrown at the top of FilesEntitlement.build when the `paths` argument is null or empty. A files entitlement with no path entries is meaningless — it would grant nothing — so the parser refuses to construct it rather than silently producing a no-op entitlement.
Source
Thrown at libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/entitlements/FilesEntitlement.java:199
return switch (baseDir) {
case "config" -> BaseDir.CONFIG;
case "data" -> BaseDir.DATA;
case "home" -> BaseDir.USER_HOME;
case "shared_data" -> BaseDir.SHARED_DATA;
// it would be nice to limit this to just ES modules, but we don't have a way to plumb that through to here
// however, we still don't document in the error case below that shared_repo and shared_data is valid
case "shared_repo" -> BaseDir.SHARED_REPO;
default -> throw new PolicyValidationException(
"invalid relative directory: " + baseDir + ", valid values: [config, data, home]"
);
};
}
@ExternalEntitlement(parameterNames = { "paths" }, esModulesOnly = false)
@SuppressWarnings("unchecked")
public static FilesEntitlement build(List<Object> paths) {
if (paths == null || paths.isEmpty()) {
throw new PolicyValidationException("must specify at least one path");
}
BiFunction<Map<String, Object>, String, String> checkString = (values, key) -> {
Object value = values.remove(key);
if (value == null) {
return null;
} else if (value instanceof String str) {
return str;
}
throw new PolicyValidationException(
"expected ["
+ key
+ "] to be type ["
+ String.class.getSimpleName()
+ "] but found type ["
+ value.getClass().getSimpleName()
+ "]"
);
};View on GitHub (pinned to db6a809a66)
Solutions
- Populate the `paths` array with at least one entry containing a `path`/`relative_path`/`path_setting` plus a `mode`.
- If you intended to grant no file access, remove the entire `files` entitlement block from the policy instead of leaving an empty list.
Example fix
// before
"files": { "paths": [] }
// after
"files": {
"paths": [
{ "relative_path": "logs", "relative_to": "home", "mode": "read" }
]
} Defensive patterns
Strategy: validation
Validate before calling
public static void validateFilesEntitlement(List<?> paths) {
if (paths == null || paths.isEmpty()) {
throw new IllegalArgumentException("files entitlement requires at least one path entry");
}
} Type guard
public static boolean hasAtLeastOnePath(List<?> paths) {
return paths != null && !paths.isEmpty();
} Prevention
- If you do not need file access, omit the files entitlement entirely.
- In policy generators, skip the block when the entries list is empty rather than emitting it.
- Add a JSON Schema minItems:1 on the paths array.
When it happens
Trigger: A policy file declares a files entitlement whose `paths` array is missing, null, or empty (e.g. `"files": { "paths": [] }` or `"files": { "paths": null }`).
Common situations: Template/policy skeleton left in place with no entries; conditional generation of policy that yielded zero entries; misunderstanding that the entitlement requires at least one declared path; YAML/JSON merge that produced an empty list.
Related errors
- invalid mode: {}, valid values: [read, read_write]
- invalid platform: {}, valid values: [linux, macos, windows]
- invalid relative directory: {}, valid values: [config, data,
- expected [{}] to be type [String] but found type [{}]
- expected [{}] to be type [boolean] but found type [{}]
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/37ad10764c76ac65.
Report an issue: GitHub.