elastic/elasticsearch · error · PolicyValidationException
invalid relative directory: {}, valid values: [config, data,
Error message
invalid relative directory: {}, valid values: [config, data, home] What it means
Thrown by FilesEntitlement.parseBaseDir when the `relative_to` (or `basedir_if_relative`) value is not one of the recognised base-directory literals. Note: the switch actually accepts five values (config, data, home, shared_data, shared_repo) but the error message only documents three (config, data, home) by design — the shared_* dirs are intentionally undocumented because they are intended for Elasticsearch-internal modules only.
Source
Thrown at libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/entitlements/FilesEntitlement.java:189
} else if (platform.equals("macos")) {
return Platform.MACOS;
} else if (platform.equals("windows")) {
return Platform.WINDOWS;
} else {
throw new PolicyValidationException("invalid platform: " + platform + ", valid values: [linux, macos, windows]");
}
}
private static BaseDir parseBaseDir(String baseDir) {
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;
}View on GitHub (pinned to db6a809a66)
Solutions
- For external plugins, use one of the documented values: "config", "data", or "home".
- If you are an Elasticsearch-internal module, "shared_data" and "shared_repo" are also accepted but intentionally undocumented in the error.
- Do not put a literal filesystem path in this field — it is a symbolic base-dir selector.
Example fix
// before
{ "relative_path": "logs", "relative_to": "/var/lib/es", "mode": "read_write" }
// after
{ "relative_path": "logs", "relative_to": "data", "mode": "read_write" } Defensive patterns
Strategy: validation
Validate before calling
private static final Set<String> PUBLIC_BASE_DIRS = Set.of("config", "data", "home");
private static final Set<String> INTERNAL_BASE_DIRS = Set.of("shared_data", "shared_repo");
public static void validateBaseDir(String dir, boolean isExternalPlugin) {
if (!PUBLIC_BASE_DIRS.contains(dir) && (!INTERNAL_BASE_DIRS.contains(dir) || isExternalPlugin)) {
throw new IllegalArgumentException("invalid base dir: " + dir);
}
} Type guard
public static boolean isValidPublicBaseDir(String d) {
return Set.of("config","data","home").contains(d);
} Prevention
- Use only config/data/home in external plugins.
- Remember the value is a symbolic selector, never a filesystem path.
- If you reach for shared_data/shared_repo as an external plugin, redesign — those are reserved.
When it happens
Trigger: A files-entitlement entry sets `relative_to` or `basedir_if_relative` to an unrecognised literal (e.g. "logs", "tmp", "base", "root", or a typo like "conf").
Common situations: Guessing a directory name; using a path-like value ("/etc/elasticsearch") instead of the symbolic literal; external plugin author trying to use shared_data/shared_repo (which is reserved for ES modules); typo in the literal.
Related errors
- a files entitlement entry must contain one of [path, relativ
- 'relative_to' may only be used with 'relative_path'
- 'basedir_if_relative' may only be used with 'path_setting'
- files entitlement with a 'relative_path' must specify 'relat
- 'relative_path' [{}] must be relative
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/cd88bee52335ec27.
Report an issue: GitHub.