apache/seatunnel · error · IllegalStateException

Python source executable

Error message

Python source executable {} is not listed in server property {}={}

What it means

PythonSourceExecutionPolicy.resolveExecutable throws this IllegalStateException when the configured python.executable, after path resolution, is not an exact (path-equal) member of the server's allowed-executables list from the PYTHON_ALLOWED_EXECUTABLES_PROPERTY system property. This server-side allowlist prevents arbitrary interpreter execution, so any unlisted binary is rejected.

Solutions

  1. Set python.executable to the exact absolute path listed in the -Dpython.allowed.executables property.
  2. On every worker, start with -Dpython.allowed.executables=/usr/bin/python3 (comma-separated absolute paths).
  3. Compare resolved paths in the error message with the allowlist to catch symlink/version differences and add the correct entry.
  4. Ensure consistency: the same property and same interpreter paths on all worker nodes.

Example fix

// before
./bin/seatunnel.sh --config job.conf  # python.executable = "python3"
// after
./bin/seatunnel.sh -Dpython.source.enabled=true \
  -Dpython.allowed.executables=/usr/bin/python3 \
  --config job.conf                    # python.executable = "/usr/bin/python3"
Defensive patterns

Strategy: validation

Validate before calling

// Java: pre-check the configured executable against the allowlist
String[] allowed = System.getProperty("python.allowed.executables", "").split(",");
String exe = configMap.get("python.executable");
boolean ok = java.util.Arrays.stream(allowed)
    .anyMatch(a -> a.equals(exe));
if (!ok) {
    throw new IllegalArgumentException(
        "python.executable " + exe + " must be one of: " + Arrays.toString(allowed));
}

Try / catch

try { Path exe = policy.resolveExecutable(cfg.getPythonExecutable()); } catch (IllegalStateException e) { LOG.error("Interpreter not in server allowlist: {}", e.getMessage()); }

Prevention

When it happens

Trigger: Calling resolveExecutable when resolveConfiguredExecutable(configuredExecutable) yields a path not matching any entry in allowedExecutables — e.g. python.executable = "python3" (relative, resolved to a different location) while the property lists only "/usr/bin/python3".

Common situations: Config uses 'python3' but the allowlist lists an absolute path; worker nodes have different interpreter locations than the master; symlinked or versioned interpreters (/usr/bin/python3.10 vs /usr/bin/python3) that do not compare equal; property set on some nodes but not others.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/9524bf3ed1f09258. Report an issue: GitHub.

Appendix: source

Thrown at seatunnel-connectors-v2/connector-python/src/main/java/org/apache/seatunnel/connectors/seatunnel/python/source/PythonSourceExecutionPolicy.java:51

final class PythonSourceExecutionPolicy {

    static final String PYTHON_SOURCE_ENABLED_PROPERTY = "seatunnel.source.python.enabled";
    static final String PYTHON_ALLOWED_EXECUTABLES_PROPERTY =
            "seatunnel.source.python.allowed-executables";

    private PythonSourceExecutionPolicy() {}

    /** Resolves the job-selected command and verifies it against the server-side allowlist. */
    static Path resolveExecutable(String configuredExecutable) throws IOException {
        ensureEnabled();
        List<Path> allowedExecutables = parseAllowedExecutables();
        Path resolvedExecutable = resolveConfiguredExecutable(configuredExecutable);
        for (Path allowedExecutable : allowedExecutables) {
            if (sameExecutablePath(resolvedExecutable, allowedExecutable)) {
                return resolvedExecutable;
            }
        }
        throw new IllegalStateException(
                "Python source executable "
                        + resolvedExecutable
                        + " is not listed in server property "
                        + PYTHON_ALLOWED_EXECUTABLES_PROPERTY
                        + "="
                        + allowedExecutables);
    }

    private static void ensureEnabled() {
        if (Boolean.parseBoolean(
                System.getProperty(PYTHON_SOURCE_ENABLED_PROPERTY, Boolean.FALSE.toString()))) {
            return;
        }
        throw new IllegalStateException(
                "Python source is disabled by the server-side security policy. Set -D"
                        + PYTHON_SOURCE_ENABLED_PROPERTY
                        + "=true and configure -D"
                        + PYTHON_ALLOWED_EXECUTABLES_PROPERTY

View on GitHub (pinned to cf67b549a7)