{"record":{"id":"e1e83f792a16f742","repo":"apache/druid","slug":"path-s-is-not-within-directory-s","errorCode":null,"errorMessage":"Path[%s] is not within directory[%s]","messagePattern":"Path\\[(.+?)\\] is not within directory\\[(.+?)\\]","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/java/util/common/FileUtils.java","lineNumber":462,"sourceCode":"      // Not expected.\n      throw new ISE(\"System property java.io.tmpdir is not set, cannot create temporary directories\");\n    }\n    return new File(parentDirectory).toPath();\n  }\n\n  /**\n   * Resolves {@code path} below {@code directory}, rejecting absolute paths and parent traversal that would escape it.\n   * This is intended for paths containing externally supplied identifiers.\n   */\n  public static File resolveFileWithinDirectory(final File directory, final String path)\n  {\n    final Path normalizedDirectory = directory.toPath().toAbsolutePath().normalize();\n    final Path childPath;\n    try {\n      childPath = Path.of(path);\n    }\n    catch (InvalidPathException e) {\n      throw new IAE(e, \"Path[%s] is not within directory[%s]\", path, directory);\n    }\n    if (childPath.isAbsolute()) {\n      throw new IAE(\"Path[%s] is not within directory[%s]\", path, directory);\n    }\n    final Path resolvedPath = normalizedDirectory.resolve(childPath).normalize();\n    if (!resolvedPath.startsWith(normalizedDirectory)) {\n      throw new IAE(\"Path[%s] is not within directory[%s]\", path, directory);\n    }\n    return resolvedPath.toFile();\n  }\n\n  @SuppressForbidden(reason = \"Files#createTempDirectory\")\n  public static File createTempDirInLocation(final Path parentDirectory, @Nullable final String prefix)\n  {\n    try {\n      final Path tmpPath = Files.createTempDirectory(\n          parentDirectory,\n          prefix == null || prefix.isEmpty() ? \"druid\" : prefix","sourceCodeStart":444,"sourceCodeEnd":480,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/java/util/common/FileUtils.java#L444-L480","documentation":"In resolveFileWithinDirectory, if the supplied path string cannot be parsed as a Path (InvalidPathException), Druid wraps that failure as IllegalArgumentException with the same 'Path[%s] is not within directory[%s]' message, treating unparseable paths as un-resolvable within the directory.","triggerScenarios":"Calling FileUtils.resolveFileWithinDirectory(directory, path) where path contains invalid characters for the filesystem (e.g. NUL byte, illegal chars on Windows) so Path.of(path) throws InvalidPathException.","commonSituations":"Segment/lock file names built from untrusted or mangled input; Windows-illegal characters in identifiers used as file names; corrupted metadata producing garbage paths.","solutions":["Sanitize/encode the path string before passing it (escape or hash illegal characters)","Catch IllegalArgumentException and surface a user-facing message about the invalid identifier","Validate identifiers used in file names at ingestion time","Use Path.of on the components rather than a pre-joined string to localize the failure"],"exampleFix":"// before\nFile f = FileUtils.resolveFileWithinDirectory(dir, untrustedName);\n// after\nString safeName = untrustedName.replaceAll(\"[\\0\\\\/<>:\\\"|?*]\", \"_\");\nFile f = FileUtils.resolveFileWithinDirectory(dir, safeName);","handlingStrategy":"validation","validationCode":"boolean safe = name != null && !name.contains(\"\\0\")\n    && name.chars().noneMatch(c -> c < 32)\n    && Path.of(name) != null; // may still throw InvalidPathException on illegal chars","typeGuard":"boolean isValidRelativeName(String s) {\n  try {\n    return s != null && !Path.of(s).isAbsolute() && !s.contains(\"..\");\n  } catch (InvalidPathException e) {\n    return false;\n  }\n}","tryCatchPattern":"try {\n  return FileUtils.resolveFileWithinDirectory(dir, path);\n} catch (IllegalArgumentException e) {\n  throw new BadRequestException(\"Invalid path: \" + path, e);\n}","preventionTips":["Sanitize or hash untrusted identifiers before using them as file names","Test file-name handling with platform-illegal characters","Reject control characters and NUL bytes at input boundaries","Normalize identifiers to a safe charset (e.g. [A-Za-z0-9._-])"],"tags":["path-validation","security","invalid-path"],"backgroundTag":"path-traversal-blocked","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}