apache/seatunnel · warning
Python source runs unsandboxed external code. Resolved…
Error message
Python source runs unsandboxed external code. Resolved executable='{}', scriptOrigin='python.script.path={}', guarded by system properties '{}','{}'. What it means
The Python source reader executes external Python code without sandboxing. At open() it resolves the configured executable, validates the script path, and logs this warning explicitly stating the risk and which system-property guards (enable flag and allowed-executables list) apply to this source.
Solutions
- Set the guard system properties explicitly (enable property and allowed-executables allowlist) to restrict which executables may run
- Point python.script.path at a trusted, version-controlled script
- Restrict python.script.path and python.executable configs via job validation; avoid running untrusted scripts in shared clusters
- Wrap the Python execution in an OS-level sandbox (container/user namespace) if untrusted input must run
Example fix
// before -Dpython.source.allowed.executables=* // after -Dpython.source.enabled=true -Dpython.source.allowed.executables=/usr/bin/python3
Defensive patterns
Strategy: validation
Validate before calling
String exe = config.get("python.executable");
Path script = Paths.get(config.get("python.script.path"));
if (!Files.exists(script)) throw new IllegalArgumentException("script not found: " + script);
if (!allowedExecutables.contains(exe)) throw new IllegalArgumentException("executable not allowlisted: " + exe); Type guard
static boolean isAllowlisted(Path executable, Set<String> allowlist) { return executable != null && allowlist.contains(executable.toString()); } Try / catch
try { reader.open(); } catch (IOException e) { /* reader closed or script path invalid */ log.error("python source open failed", e); } Prevention
- Set the enable and allowed-executables system properties explicitly
- Version-control and audit the python script
- Run python sources in containers, never on shared bare metal
- Restrict python.script.path to a trusted directory
When it happens
Trigger: PythonSourceReader.open() is called and the reader starts the Python process; logged every time the source opens, showing resolvedExecutable, the python.script.path value, and the two guard properties PYTHON_SOURCE_ENABLED_PROPERTY and PYTHON_ALLOWED_EXECUTABLES_PROPERTY.
Common situations: Security review of jobs using the Python source; deployments where the configured executable could be swapped for an arbitrary interpreter; running untrusted scripts in shared clusters.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- Python source allowlist entry must be an absolute path
- Server property does not contain a usable absolute path
- Server property must contain at least one absolute…
- ANTHROPIC_API_KEY environment variable is required for…
- anthropic package required for AI_PROVIDER=anthropic…
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/db8965a116b699ec.
Report an issue: GitHub.
Appendix: source
Thrown at seatunnel-connectors-v2/connector-python/src/main/java/org/apache/seatunnel/connectors/seatunnel/python/source/PythonSourceReader.java:132
this.sourceConfig = sourceConfig;
this.catalogTable = catalogTable;
this.readerContext = readerContext;
this.deserializationSchema = createDeserializationSchema(sourceConfig, catalogTable);
this.recentStderrLines = new ArrayDeque<>(STDERR_HISTORY_LIMIT);
this.stdoutLines = new ArrayBlockingQueue<>(STDOUT_QUEUE_CAPACITY);
}
@Override
public void open() throws Exception {
synchronized (lifecycleLock) {
if (closeRequested) {
throw new IOException("Python source reader has already been closed");
}
}
Path scriptPath = validateScriptPath().toAbsolutePath().normalize();
Path resolvedExecutable =
PythonSourceExecutionPolicy.resolveExecutable(sourceConfig.getPythonExecutable());
LOG.warn(
"Python source runs unsandboxed external code. Resolved executable='{}', scriptOrigin='python.script.path={}', guarded by system properties '{}','{}'.",
resolvedExecutable,
scriptPath,
PythonSourceExecutionPolicy.PYTHON_SOURCE_ENABLED_PROPERTY,
PythonSourceExecutionPolicy.PYTHON_ALLOWED_EXECUTABLES_PROPERTY);
ProcessBuilder processBuilder =
new ProcessBuilder(resolvedExecutable.toString(), scriptPath.toString());
configureWorkingDirectory(processBuilder, scriptPath);
synchronized (lifecycleLock) {
if (closeRequested) {
throw new IOException("Python source reader has already been closed");
}
try {
this.process = processBuilder.start();
} catch (IOException e) {
throw new IOException(
"Failed to start python source process with executable ["View on GitHub (pinned to cf67b549a7)