gohugoio/hugo · error
pandoc not found in $PATH, cannot render
Error message
pandoc not found in $PATH, cannot render %q
What it means
Returned by the pandoc converter when getPandocBinaryName() cannot find the 'pandoc' executable in $PATH (via hexec.InPath). Hugo shells out to pandoc as an external renderer, so if the binary is absent the .pandoc content file cannot be rendered and conversion aborts for that document.
Solutions
- Install pandoc and ensure it is on PATH: `apt-get install -y pandoc` (Debian/Ubuntu), `brew install pandoc` (macOS), `apk add --no-cache pandoc` (Alpine).
- Verify with `pandoc --version` in the same shell/environment Hugo runs in.
- If you do not need pandoc, stop routing content to it: remove/alter the media type mapping or switch defaultMarkdownHandler away from pandoc, and rename .pandoc files to .md.
- For Docker builds add a pandoc install layer before the Hugo build step.
Example fix
# Dockerfile before FROM hugomods/hugo:exts # pandoc missing -> render fails # after FROM hugomods/hugo:exts RUN apk add --no-cache pandoc
Defensive patterns
Strategy: validation
Validate before calling
// Check pandoc availability before building.
import "github.com/gohugoio/hugo/common/hexec"
func ensurePandoc() error {
if !hexec.InPath("pandoc") {
return fmt.Errorf("pandoc not installed; install it or remove .pandoc content")
}
return nil
} Try / catch
if _, err := pandocconv.Convert(rc); err != nil {
if strings.Contains(err.Error(), "pandoc not found in $PATH") {
// skip or report the document, do not abort the whole build
}
} Prevention
- Add an `which pandoc` check to your build script and CI pipeline.
- Document external binary dependencies (pandoc) in your project README.
- Pin a pandoc version in your Dockerfile so CI is reproducible.
When it happens
Trigger: Rendering any content file mapped to the pandoc converter (extension resolved to the pandoc media type, or defaultMarkdownHandler/error path selecting pandoc) on a machine where `pandoc` is not on PATH. Fires from pandocConverter.getPandocContent -> Convert during the build.
Common situations: CI container or Docker image that did not install pandoc; local dev machine with pandoc installed via a package manager that didn't add it to PATH; deploying to a minimal Hugo image (e.g. the extended Alpine image) that only bundles Hugo; relying on pandoc in a theme without documenting the external dependency.
Related errors
- rst2html / rst2html.py not found in $PATH, cannot render
- no Dart Sass binary found in $PATH
- failed to execute 'go
- failed to process shortcode
- git clone
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/8d15b1a4ec12350b.
Report an issue: GitHub.
Appendix: 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 52c9bd7908)