gohugoio/hugo · error

rst2html / rst2html.py not found in $PATH, cannot render

Error message

rst2html / rst2html.py not found in $PATH, cannot render %q

What it means

Returned by the rst converter when getRstBinaryNameAndPath() finds neither 'rst2html' nor 'rst2html.py' in $PATH (checked via hexec.LookPath). Hugo invokes rst2html as an external Python tool to convert reStructuredText; without it, RST content cannot be rendered.

Solutions

  1. Install docutils: `pip install docutils` (or `pip3 install docutils`), which provides rst2html/rst2html.py.
  2. Confirm `which rst2html || which rst2html.py` (or `where` on Windows) succeeds in Hugo's environment.
  3. On Debian/Ubuntu: `apt-get install -y python3-docutils`; on macOS: `brew install docutils`.
  4. If RST is not needed, remove the .rst files or reconfigure the markup so rst is not selected.

Example fix

# before: rst2html missing
pip install --no-input mkdocs   # docutils not pulled in

# after
pip install docutils
Defensive patterns

Strategy: validation

Validate before calling

// Check for rst2html before building RST content.
import "os/exec"

func ensureRst2html() error {
    for _, c := range []string{"rst2html", "rst2html.py"} {
        if p, err := exec.LookPath(c); err == nil && p != "" {
            return nil
        }
    }
    return fmt.Errorf("rst2html not found; run: pip install docutils")
}

Try / catch

if _, err := rstconv.Convert(rc); err != nil {
    if strings.Contains(err.Error(), "rst2html / rst2html.py not found") {
        // log install hint and continue without RST rendering
    }
}

Prevention

When it happens

Trigger: Building any .rst content file on a host lacking both rst2html and rst2html.py. Fires from rstConverter.getRstContent -> Convert during content rendering.

Common situations: Python docutils not installed (`pip install docutils` provides rst2html); CI image without Python toolchain; a host where rst2html is installed but only under a virtualenv not active when Hugo runs; Windows machines where the binary needs the explicit .py suffix and the Python interpreter.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/f5e2508e2d18d250. Report an issue: GitHub.

Appendix: source

Thrown at markup/rst/convert.go:70

	b, err := c.getRstContent(ctx.Src, c.ctx)
	if err != nil {
		return nil, err
	}
	return converter.Bytes(b), nil
}

func (c *rstConverter) Supports(feature identity.Identity) bool {
	return false
}

// getRstContent calls the Python script rst2html as an external helper
// to convert reStructuredText content to HTML.
func (c *rstConverter) getRstContent(src []byte, ctx converter.DocumentContext) ([]byte, error) {
	logger := c.cfg.Logger
	binaryName, binaryPath := getRstBinaryNameAndPath()

	if binaryName == "" {
		return nil, fmt.Errorf("rst2html / rst2html.py not found in $PATH, cannot render %q", ctx.DocumentName)
	}

	logger.Infoln("Rendering", ctx.DocumentName, "with", binaryName, "...")

	args := []string{"--leave-comments", "--initial-header-level=2"}
	if c.cfg.Conf != nil && c.cfg.MarkupConfig().RST.SyntaxHighlight != "long" {
		args = append(args, "--syntax-highlight="+c.cfg.MarkupConfig().RST.SyntaxHighlight)
	}

	var result []byte
	var err error

	// certain *nix based OSs wrap executables in scripted launchers
	// invoking binaries on these OSs via python interpreter causes SyntaxError
	// invoke directly so that shebangs work as expected
	// handle Windows manually because it doesn't do shebangs
	if runtime.GOOS == "windows" {
		pythonBinary, _ := internal.GetPythonBinaryAndExecPath()

View on GitHub (pinned to 52c9bd7908)