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

  1. Install the missing external tool matching the markup name (e.g. `gem install asciidoctor` for asciidocext, ensure pandoc is on PATH for pandoc).
  2. Check the file extension / front matter `markup` field for typos and correct it to a registered name (markdown, asciidocext, org, pandoc, rst).
  3. Convert the affected file to Markdown if the external tool cannot be installed in the build environment.
  4. 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

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


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)