gohugoio/hugo · error

no content renderer found for markup %q, page: %s

Error message

no content renderer found for markup %q, page: %s

What it means

When creating a content converter for a page, Hugo looks up a registered content renderer (goldmark, asciidocext, pandoc, rst, org, html) by the page's markup identifier. If ContentSpec.Converters.Get returns nil — the markup name is unknown or its external helper/config is unavailable — Hugo returns this error instead of rendering, naming the page for diagnosis.

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 8a468df065)

Solutions

  1. Fix the `markup` value in front matter to a supported identifier (markdown/goldmark, html, asciidocext, pandoc, rst, org) or remove it to use the extension-based default.
  2. If using AsciiDoc/Pandoc/RST, install the external binary (asciidoctor, pandoc, rst2html) and allow it under security.exec.allow in the site config.
  3. If upgrading from an old Hugo that used blackfriday, switch the content to goldmark-compatible markdown.

Example fix

# before
---
markup: mardown
---
# after
---
markup: markdown
---
Defensive patterns

Strategy: validation

Validate before calling

// Verify markup format is registered before assigning it to content
valid := map[string]bool{"markdown": true, "html": true, "goldmark": true, "asciidocext": true, "pandoc": true, "rst": true, "org": true, "emacs-org-mode": true}
if m, ok := fm["markup"].(string); ok && !valid[strings.ToLower(m)] {
    return fmt.Errorf("unknown markup %q", m)
}

Type guard

func markupSupported(m string) bool {
    switch strings.ToLower(m) {
    case "", "markdown", "goldmark", "html", "org", "emacs-org-mode", "asciidocext", "pandoc", "rst":
        return true
    }
    return false
}

Try / catch

if err := site.Build(); err != nil {
    if strings.Contains(err.Error(), "no content renderer found for markup") {
        // either fix the markup value/file extension, or install the external tool (asciidoctor, pandoc, rst2html)
    }
    return err
}

Prevention

When it happens

Trigger: A page sets `markup: something` in front matter (or has a file extension) that doesn't match any registered converter, e.g. `markup: markdown2`, `markup: asciidoc` when security.exec doesn't allow the asciidoctor binary registration, or a typo like `mardown`.

Common situations: Typos in the markup front matter field, using .ad/.rst/.pandoc content without installing the external tool, version upgrades where a markup engine was removed (e.g. blackfriday removed in Hugo 0.100), or content copied from another site using a different engine.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/585e8d71dd86f170.json. Report an issue: GitHub ↗.