apache/beam · error · RuntimeError

Graphviz dot executable not available for rendering non-dot…

Error message

Graphviz dot executable not available for rendering non-dot output files {non_dot_files}

What it means

When the Graphviz 'dot' executable is unavailable, the renderer can only write raw .dot text files. If any requested --render_output files are non-dot formats (png, svg, etc.), it raises RuntimeError chained from the original 'dot -V' failure, listing the unrenderable files.

Solutions

  1. Install Graphviz so the dot executable is available (apt-get install graphviz / brew install graphviz / choco install graphviz)
  2. Verify with 'dot -V' that dot is on PATH
  3. Render to a .dot file instead, and convert it elsewhere where graphviz exists

Example fix

# before
--render_output=graph.png   # on host without graphviz
# after
apt-get install -y graphviz && dot -V  # then rerun with --render_output=graph.png
Defensive patterns

Strategy: fallback

Validate before calling

import shutil
non_dot = [o for o in render_outputs if not o.endswith('.dot')]
if non_dot and shutil.which('dot') is None:
    raise SystemExit('Install graphviz (apt-get install graphviz) for non-dot render outputs')

Type guard

def graphviz_available() -> bool:
    import shutil
    return shutil.which('dot') is not None

Try / catch

try:
    result = pipeline.run()
except RuntimeError as e:
    if 'dot executable not available' in str(e):
        outputs = [o for o in render_outputs if o.endswith('.dot')]  # fallback: dot text only
        rerun_with_outputs(outputs)
    else:
        raise

Prevention

When it happens

Trigger: Requesting --render_output=graph.png (or .svg/.jpg) on a machine where graphviz is not installed, so 'dot -V' fails and non-dot outputs cannot be produced.

Common situations: CI containers or slim Docker images without graphviz; forgetting to install graphviz after switching output format from .dot to .png; macOS/Windows dev machines missing the dot binary.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/0317c911cef079ea. Report an issue: GitHub.

Appendix: source

Thrown at sdks/python/apache_beam/runners/render.py:428

    if render_options.log_proto:
      _LOGGER.info(pipeline_proto)
    renderer = PipelineRenderer(pipeline_proto, render_options)
    try:
      subprocess.run(['dot', '-V'], capture_output=True, check=True)
    except FileNotFoundError as exn:
      # If dot is not available, we can at least output the raw .dot files.
      dot_files = [
          output for output in render_options.render_output
          if output.endswith('.dot')
      ]
      for output in dot_files:
        with open(output, 'w') as fout:
          fout.write(renderer.to_dot())
          _LOGGER.info("Wrote pipeline as %s", output)

      non_dot_files = set(render_options.render_output) - set(dot_files)
      if non_dot_files:
        raise RuntimeError(
            "Graphviz dot executable not available "
            f"for rendering non-dot output files {non_dot_files}") from exn
      elif render_options.render_port >= 0:
        raise RuntimeError(
            "Graphviz dot executable not available for serving") from exn

      return RenderPipelineResult(None)

    renderer.page()

    if render_options.render_port >= 0:
      # TODO: If this gets more complex, we could consider taking on a
      # framework like Flask as a dependency.
      class RequestHandler(http.server.BaseHTTPRequestHandler):
        def do_GET(self):
          parts = urllib.parse.urlparse(self.path)
          args = urllib.parse.parse_qs(parts.query)
          renderer.update(**args)

View on GitHub (pinned to 12126d8942)