kestra-io/kestra · error · SecurityException

The path {} is not authorized. Path must be allowed either g

Error message

The path {} is not authorized. Path must be allowed either globally inside the Kestra configuration using the `kestra.local-files.allowed-paths` property.

What it means

Thrown by `DefaultLocalPath.checkPath` — the variant of `LocalPath` created WITHOUT a `RunContext` (`createLocalPath()`). Because there is no working directory or plugin config to consult, the ONLY allowed locations are the globally-configured `kestra.local-files.allowed-paths`. If the resolved real path is not under one of those, a `SecurityException` is thrown.

Source

Thrown at core/src/main/java/io/kestra/core/runners/LocalPathFactory.java:143

            }

            return path;
        }
    }

    static class DefaultLocalPath extends AbstractLocalPath {
        private final List<Path> globalAllowedPaths;

        DefaultLocalPath(List<Path> globalAllowedPaths) {
            this.globalAllowedPaths = globalAllowedPaths;
        }

        @Override
        protected Path checkPath(URI uri) throws IOException {
            Path path = Path.of(uri).toRealPath(); // toRealPath() will protect about path traversal issues
            // we only allow globally allowed as we don't have a run context to get the working directory nor the plugin configuration
            if (globalAllowedPaths.stream().noneMatch(path::startsWith)) {
                throw new SecurityException(
                    "The path " + path + " is not authorized. " +
                        "Path must be allowed either globally inside the Kestra configuration using the `" + LocalPath.ALLOWED_PATHS_CONFIG + "` property."
                );
            }

            return path;
        }
    }
}

View on GitHub (pinned to 823fada927)

Solutions

  1. Prefer `createLocalPath(runContext)` when a RunContext is available — it also permits the working directory and plugin paths.
  2. Configure `kestra.local-files.allowed-paths` to include the required directories.
  3. Move the file access into task execution so a RunContext is present.

Example fix

// before — no RunContext, only global allow-list applies
LocalPath lp = localPathFactory.createLocalPath();
lp.get(URI.create("file:///data/input.csv")); // throws if /data not allowed

// after — use the RunContext-aware variant
LocalPath lp = localPathFactory.createLocalPath(runContext);
lp.get(URI.create("file:///data/input.csv")); // ok if /data is plugin-allowed or in working dir
Defensive patterns

Strategy: validation

Validate before calling

// Prefer the RunContext-aware variant; only use createLocalPath() when unavoidable
LocalPath lp = (runContext != null)
    ? localPathFactory.createLocalPath(runContext)
    : localPathFactory.createLocalPath();
// for the no-context variant, ensure the target is under a globally allowed path

Try / catch

try {
    return lp.get(uri);
} catch (SecurityException e) {
    throw new SecurityException("Path not in global allowed-paths ('" + LocalPath.ALLOWED_PATHS_CONFIG + "'): " + uri, e);
}

Prevention

When it happens

Trigger: Code that calls `localPathFactory.createLocalPath()` (no RunContext) and then resolves a `file://` URI pointing outside the globally-allowed paths. Typically internal/utility callers that run outside a task's execution context (e.g. bootstrap, CLI, or a service that has no working dir).

Common situations: A plugin or service resolving local files before a RunContext exists; misconfigured `kestra.local-files.allowed-paths` on a fresh deployment; an absolute path that worked with the RunContext variant but fails with the default variant because no global allow-list is set.

Related errors


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