kestra-io/kestra · error · IllegalArgumentException

The path to resolve must be a relative path inside the curre

Error message

The path to resolve must be a relative path inside the current working directory.

What it means

Thrown by `LocalWorkingDir.resolve(Path)` when the supplied path string contains the parent-directory sequence `..` followed by the platform file separator. This is the first of two path-traversal guards in `resolve`: it rejects any literal `..` segment before normalization. Thrown as `IllegalArgumentException`. The working directory is a sandbox; escaping it via `..` is forbidden.

Source

Thrown at core/src/main/java/io/kestra/core/runners/LocalWorkingDir.java:92

    public synchronized Path path(boolean create) {
        if (create && !this.workingDirPath.toFile().exists()) {
            //noinspection ResultOfMethodCallIgnored
            this.workingDirPath.toFile().mkdirs();
        }
        return this.workingDirPath;
    }

    /**
     * {@inheritDoc}
     **/
    @Override
    public Path resolve(Path path) {
        if (path == null) {
            return path();
        }

        if (path.toString().contains(".." + File.separator)) {
            throw new IllegalArgumentException("The path to resolve must be a relative path inside the current working directory.");
        }

        Path baseDir = path();
        Path resolved = baseDir.resolve(path).toAbsolutePath();

        if (!resolved.startsWith(baseDir)) {
            throw new IllegalArgumentException("The path to resolve must be a relative path inside the current working directory.");
        }

        return resolved;
    }

    /**
     * {@inheritDoc}
     **/
    @Override
    public Path createTempFile() throws IOException {
        return createTempFile(null, null);

View on GitHub (pinned to 823fada927)

Solutions

  1. Strip or reject `..` segments from untrusted filenames before resolving.
  2. Use a plain relative filename with no parent reference.
  3. If subdirectories are needed, use forward relative segments like `subdir/file.txt`.

Example fix

// before
Path p = workingDir.resolve(Path.of("../../etc/hosts"));

// after — sanitize and keep relative
String name = raw.replaceAll("\\.\\.[\\/\\\\]", "");
Path p = workingDir.resolve(Path.of(name));
Defensive patterns

Strategy: validation

Validate before calling

String raw = filename;
if (raw != null && raw.contains(".." + File.separator)) {
    throw new IllegalArgumentException("Filename must not contain parent-directory references: " + raw);
}
return workingDir.resolve(Path.of(raw));

Type guard

static boolean isSafeRelativePath(String name) {
    return name != null && !name.isBlank()
        && !name.contains(".." + File.separator)
        && !name.contains("../") && !name.contains("..\\");
}

Prevention

When it happens

Trigger: Calling `workingDir.resolve(Path.of("../escape.txt"))` or any path containing `..` + separator — e.g. a filename derived from user input or a Pebble-rendered value that includes `..`. Common when a task constructs a filename from an untrusted source.

Common situations: A download/filename task whose name comes from an HTTP header or URL path containing `..`; test code using relative `..` paths; refactoring a path join that previously relied on a different base.

Related errors


AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14). Data as JSON: /api/errors/50780d5942ec71bd. Report an issue: GitHub.