gohugoio/hugo · error
no content renderer found for markup
Error message
no content renderer found for markup %q, page: %s
What it means
Hugo could not find a content converter (renderer) for the markup type declared on a page. The converter registry at markup/markup.go:123 looks up providers by lowercased markup name; when none is registered for that name, page__meta.go:990 returns a NopConverter and this error. Built-in markup names include markdown (goldmark), asciidocext, org, pandoc, rst — the last three require the external binary to be available at build time.
Solutions
- Install the missing external tool matching the markup name (e.g. `gem install asciidoctor` for asciidocext, ensure pandoc is on PATH for pandoc).
- Check the file extension / front matter `markup` field for typos and correct it to a registered name (markdown, asciidocext, org, pandoc, rst).
- Convert the affected file to Markdown if the external tool cannot be installed in the build environment.
- Register a custom converter provider if you intentionally added a new markup type.
Example fix
# before (file: posts/a.adoc with no asciidoctor installed) markup: asciidocext # after: install the tool gem install asciidoctor # or rename/convert the file to Markdown mv posts/a.adoc posts/a.md
Defensive patterns
Strategy: validation
Validate before calling
# Before building, verify each markup type used in content has a converter. # Markdown/asciidocext/etc.: for tool in asciidoctor pandoc emacs; do command -v $tool >/dev/null || echo "missing: $tool"; done # List markup types referenced in your content: # find content -type f | sed 's/.*\.//' | sort -u
Prevention
- Keep a build-time check (CI step) that asserts required external converters (asciidoctor, pandoc, emacs) are installed when content uses those markups.
- Restrict content file extensions to markdown unless an external converter is intentionally used.
- Document the markup identifier (lowercase, e.g. asciidocext not asciidoc) in your project README.
When it happens
Trigger: A content file declares an unsupported markup extension (e.g. .adoc, .org, .pandoc, .rst) while the corresponding external tool is not installed; a typo in the markup front matter field; a custom markup type that was never registered via markup.conversion config; or a built-in-only markup like asciidocext used without asciidoctor on PATH.
Common situations: Switching a site from Markdown to AsciiDoc/org-mode/RST without installing asciidoctor/emacs/pandoc; copying content from another SSG that uses an unknown markup identifier; a CI image that lacks the external converter binary; renaming a file extension to something Hugo does not map.
Related errors
- ContentMediaType not set
- failed to resolve media type for suffix
- failed to resolve media type for
- too many arguments, expected 0 or 1
- unrecognized render hook template
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/585e8d71dd86f170.
Report an issue: GitHub.
Appendix: source
Thrown at hugolib/page__meta.go:990
m.pageConfig.Title = strings.Replace(s.conf.C.CreateTitle(m.pathInfo.Unnormalized().BaseNameNoIdentifier()), "-", " ", -1)
} else {
m.pageConfig.Title = strings.Replace(m.pathInfo.Unnormalized().BaseNameNoIdentifier(), "-", " ", -1)
}
case kinds.KindStatus404:
m.pageConfig.Title = "404 Page not found"
}
}
return nil
}
func (m *pageMeta) newContentConverter(ps *pageState, markup string) (converter.Converter, error) {
if ps == nil {
panic("no Page provided")
}
cp := ps.s.ContentSpec.Converters.Get(markup)
if cp == nil {
return converter.NopConverter, fmt.Errorf("no content renderer found for markup %q, page: %s", markup, ps.getPageInfoForError())
}
var filename string
var path string
if m.f != nil {
filename = m.f.Filename()
path = m.f.Path()
} else {
path = m.Path()
}
doc := newPageForRenderHook(ps)
documentLookup := func(id uint64) any {
if id == ps.pid {
// This prevents infinite recursion in some cases.
return doc
}View on GitHub (pinned to 52c9bd7908)