elastic/elasticsearch · error · PolicyValidationException
files entitlement with a 'relative_path' must specify 'relat
Error message
files entitlement with a 'relative_path' must specify 'relative_to'
What it means
Thrown when `relative_path` is present on a files-entitlement entry but `relative_to` is missing. A relative path is ambiguous without a base directory to resolve against, so the parser requires the companion `relative_to` field to name the anchor (config/data/home/shared_data/shared_repo).
Source
Thrown at libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/entitlements/FilesEntitlement.java:278
}
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) {
throw new PolicyValidationException("'basedir_if_relative' may only be used with 'path_setting'");
}
final FileData fileData;
if (relativePathAsString != null) {
if (relativeTo == null) {
throw new PolicyValidationException("files entitlement with a 'relative_path' must specify 'relative_to'");
}
BaseDir baseDir = parseBaseDir(relativeTo);
Path relativePath = Path.of(relativePathAsString);
if (FileUtils.isAbsolutePath(relativePathAsString)) {
throw new PolicyValidationException("'relative_path' [" + relativePathAsString + "] must be relative");
}
fileData = FileData.ofRelativePath(relativePath, baseDir, mode);
} else if (pathAsString != null) {
Path path = Path.of(pathAsString);
if (FileUtils.isAbsolutePath(pathAsString) == false) {
throw new PolicyValidationException("'path' [" + pathAsString + "] must be absolute");
}
fileData = FileData.ofPath(path, mode);
} else if (pathSetting != null) {
if (settingBaseDirAsString == null) {
throw new PolicyValidationException("files entitlement with a 'path_setting' must specify 'basedir_if_relative'");
}
BaseDir baseDir = parseBaseDir(settingBaseDirAsString);View on GitHub (pinned to db6a809a66)
Solutions
- Add `"relative_to": "<base>"` where <base> is one of config, data, home (or shared_data/shared_repo for internal modules).
- If you actually meant an absolute path, switch to `path` instead of `relative_path`.
Example fix
// before
{ "relative_path": "logs", "mode": "read" }
// after
{ "relative_path": "logs", "relative_to": "home", "mode": "read" } Defensive patterns
Strategy: validation
Validate before calling
public static void validateRelativePathPairing(Map<String,Object> entry) {
if (entry.containsKey("relative_path") && !entry.containsKey("relative_to")) {
throw new IllegalArgumentException("relative_path requires relative_to");
}
} Type guard
public static boolean relativePathOk(Map<String,Object> e) {
return !e.containsKey("relative_path") || e.containsKey("relative_to");
} Prevention
- Always emit relative_to alongside relative_path.
- If you meant an absolute path, switch to the `path` field instead.
- Enforce the pairing via a JSON Schema if/then rule.
When it happens
Trigger: An entry has `relative_path` but no `relative_to`, e.g. `{ "relative_path": "logs", "mode": "read" }`.
Common situations: Author assumes a default base dir; forgot the companion field; template missing the line; refactor that renamed or removed `relative_to`.
Related errors
- invalid relative directory: {}, valid values: [config, data,
- 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'
- 'relative_path' [{}] must be relative
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/40d5c26af2199821.
Report an issue: GitHub.