gohugoio/hugo · error
pandoc not found in $PATH, cannot render %q
Error message
pandoc not found in $PATH, cannot render %q
What it means
Hugo renders Pandoc-flavored content by shelling out to the external `pandoc` binary. Before spawning it, `getPandocContent` checks `hexec.InPath("pandoc")`; if the binary isn't on $PATH the page cannot be converted and the build fails with the document name that triggered it.
Source
Thrown at markup/pandoc/convert.go:63
}
func (c *pandocConverter) Convert(ctx converter.RenderContext) (converter.ResultRender, error) {
b, err := c.getPandocContent(ctx.Src, c.ctx)
if err != nil {
return nil, err
}
return converter.Bytes(b), nil
}
func (c *pandocConverter) Supports(feature identity.Identity) bool {
return false
}
// getPandocContent calls pandoc as an external helper to convert pandoc markdown to HTML.
func (c *pandocConverter) getPandocContent(src []byte, ctx converter.DocumentContext) ([]byte, error) {
binaryName := getPandocBinaryName()
if binaryName == "" {
return nil, fmt.Errorf("pandoc not found in $PATH, cannot render %q", ctx.DocumentName)
}
args := []string{"--mathjax", "--citeproc"}
return internal.ExternallyRenderContent(c.cfg, ctx, src, binaryName, args)
}
const pandocBinary = "pandoc"
func getPandocBinaryName() string {
if hexec.InPath(pandocBinary) {
return pandocBinary
}
return ""
}
// Supports returns whether Pandoc is installed on this computer.
func Supports() bool {
hasBin := getPandocBinaryName() != ""
if htesting.SupportsAll() {View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Install pandoc and ensure it's on $PATH for the Hugo process (e.g. `apt-get install pandoc` in CI, `brew install pandoc` locally), then restart `hugo server`.
- In CI, add a pandoc install step before the Hugo build, or use an image that bundles it.
- If pandoc isn't wanted, change the offending content file's markup to goldmark markdown (rename to .md or set `markup: goldmark`).
- Note Hugo's security policy must also allow executing pandoc (`security.exec.allow`).
Example fix
# before (CI) hugo --minify # after (CI) apt-get update && apt-get install -y pandoc hugo --minify
Defensive patterns
Strategy: validation
Validate before calling
if _, err := exec.LookPath("pandoc"); err != nil {
return fmt.Errorf("pandoc required for .pad/.pandoc content but not installed: %w", err)
} Prevention
- Install pandoc and ensure it's on $PATH in every build environment, including CI containers
- Add a preflight check (exec.LookPath or `pandoc --version`) to build scripts
- Whitelist pandoc in Hugo's security.exec.allow config
- Avoid pandoc-format content files if you cannot guarantee the binary in all environments
When it happens
Trigger: Building a site containing a content file with a `.pad`/`.pdc` extension (or `markup: pandoc` in front matter) on a machine where the `pandoc` executable is not resolvable via $PATH at Hugo's process start.
Common situations: CI containers and the official Hugo Docker images that don't include pandoc; pandoc installed after starting `hugo server` (PATH is snapshotted); pandoc installed via a user-local path not exported to the environment running Hugo; Netlify/Vercel builds missing an install step.
Related errors
- rst2html / rst2html.py not found in $PATH, cannot render %q
- no Dart Sass binary found in $PATH
- asciidoctor not found in $PATH, cannot render %q
- failed to resolve output path %q: %w
- abort: jekyll root contains neither posts nor drafts
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/8d15b1a4ec12350b.json.
Report an issue: GitHub ↗.