{"record":{"id":"0364cf00cc7ed631","repo":"apache/beam","slug":"unable-to-find-a-suitable-python-executable","errorCode":null,"errorMessage":"Unable to find a suitable Python executable.","messagePattern":"Unable to find a suitable Python executable\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"critical","filePath":"sdks/java/extensions/python/src/main/java/org/apache/beam/sdk/extensions/python/PythonService.java","lineNumber":150,"sourceCode":"    LOG.info(\"Starting python service with arguments {}\", command);\n    Process p =\n        new ProcessBuilder(command)\n            .redirectError(ProcessBuilder.Redirect.INHERIT)\n            .redirectOutput(ProcessBuilder.Redirect.INHERIT)\n            .start();\n    return p::destroy;\n  }\n\n  private String whichPython() {\n    for (String executable : ImmutableList.of(\"python3\", \"python\")) {\n      try {\n        new ProcessBuilder(executable, \"--version\").start().waitFor();\n        return executable;\n      } catch (IOException | InterruptedException exn) {\n        // Ignore.\n      }\n    }\n    throw new RuntimeException(\"Unable to find a suitable Python executable.\");\n  }\n\n  @VisibleForTesting\n  static String getMatchingStablePythonSDKVersion(String javaSDKVersion) {\n    if (javaSDKVersion == null) {\n      return \"latest\";\n    } else if (javaSDKVersion.endsWith(\".dev\")) {\n      return \"latest\";\n    } else {\n      return javaSDKVersion;\n    }\n  }\n\n  public static int findAvailablePort() throws IOException {\n    ServerSocket s = new ServerSocket(0);\n    try {\n      return s.getLocalPort();\n    } finally {","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/java/extensions/python/src/main/java/org/apache/beam/sdk/extensions/python/PythonService.java#L132-L168","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n// (no python on PATH) java -jar pipeline.jar\n// after\nPATH=/usr/bin:$PATH java -jar pipeline.jar\n# or in code\nPythonService.setPythonExecutable(\"/usr/bin/python3.9\");","handlingStrategy":"fallback","validationCode":"boolean pythonAvailable = true;\ntry {\n  new ProcessBuilder(\"python3\", \"--version\").start().waitFor();\n} catch (Exception exn) { pythonAvailable = false; }\nif (!pythonAvailable) { /* set explicit executable or fail fast */ }","typeGuard":null,"tryCatchPattern":"try {\n  service.start();\n} catch (RuntimeException e) {\n  if (e.getMessage().contains(\"Unable to find a suitable Python executable\")) {\n    PythonService.setPythonExecutable(\"/usr/bin/python3\");\n    service.start();\n  }\n}","preventionTips":["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"],"tags":["java","python","environment","path","dependency"],"backgroundTag":"missing-dependency","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-15T13:17:12.816Z"}