apache/beam · critical · RuntimeException
Unable to find a suitable Python executable.
Error message
Unable to find a suitable Python executable.
What it means
PythonService.whichPython probes a list of candidate Python interpreters by running '<python> --version'. If none can be executed successfully, the library throws RuntimeException stating it cannot find a suitable Python executable. A valid Python 3 on PATH is required to run the expansion/bootstrap service.
Solutions
- Install a supported Python 3 interpreter and ensure it is on PATH
- Set the interpreter explicitly via PythonService.setPythonExecutable("/path/to/python3") or the equivalent option/flag
- Verify with `<python> --version` in the exact environment running the JVM
- Check PATH inside containers/IDE run configs, which may differ from your shell
Example fix
// before
// (no python on PATH) java -jar pipeline.jar
// after
PATH=/usr/bin:$PATH java -jar pipeline.jar
# or in code
PythonService.setPythonExecutable("/usr/bin/python3.9"); Defensive patterns
Strategy: fallback
Validate before calling
boolean pythonAvailable = true;
try {
new ProcessBuilder("python3", "--version").start().waitFor();
} catch (Exception exn) { pythonAvailable = false; }
if (!pythonAvailable) { /* set explicit executable or fail fast */ } Try / catch
try {
service.start();
} catch (RuntimeException e) {
if (e.getMessage().contains("Unable to find a suitable Python executable")) {
PythonService.setPythonExecutable("/usr/bin/python3");
service.start();
}
} Prevention
- Install Python 3 in all environments running the pipeline (Docker images, CI agents)
- Set the interpreter explicitly instead of relying on PATH
- Keep PATH consistent between shells, IDE run configs, and containers
- Verify `<python> --version` works as a health check before launching jobs
When it happens
Trigger: No python/python3 binary on PATH; python exists but fails --version (broken install, missing shared libs); only Python 2 installed; PATH inside the JVM/IDE/container differs from the shell.
Common situations: Docker images without Python; IDE run configurations with a minimal PATH; renamed interpreters (python3 vs python); version mismatch with the matching stable SDK version list.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- No proto encoding for PaneInfoCoder, always part of Windowed
- Python bootstrap failed with error ${result}, ${lastNonEmpty
- Java is not correctly installed in JAVA_HOME=%s to use this
- Java must be installed on this system to use this transform/
- Timing number 0b" + timingNumber.toString(2) + " has more th
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/0364cf00cc7ed631.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/extensions/python/src/main/java/org/apache/beam/sdk/extensions/python/PythonService.java:150
LOG.info("Starting python service with arguments {}", command);
Process p =
new ProcessBuilder(command)
.redirectError(ProcessBuilder.Redirect.INHERIT)
.redirectOutput(ProcessBuilder.Redirect.INHERIT)
.start();
return p::destroy;
}
private String whichPython() {
for (String executable : ImmutableList.of("python3", "python")) {
try {
new ProcessBuilder(executable, "--version").start().waitFor();
return executable;
} catch (IOException | InterruptedException exn) {
// Ignore.
}
}
throw new RuntimeException("Unable to find a suitable Python executable.");
}
@VisibleForTesting
static String getMatchingStablePythonSDKVersion(String javaSDKVersion) {
if (javaSDKVersion == null) {
return "latest";
} else if (javaSDKVersion.endsWith(".dev")) {
return "latest";
} else {
return javaSDKVersion;
}
}
public static int findAvailablePort() throws IOException {
ServerSocket s = new ServerSocket(0);
try {
return s.getLocalPort();
} finally {View on GitHub (pinned to 12126d8942)