gohugoio/hugo · error
timed out rendering the page content. Extend the `timeout` l
Error message
timed out rendering the page content. Extend the `timeout` limit in your Hugo config file: %w
What it means
Returned from the plain-content computation in page__content.go when rendering a page's content exceeds Hugo's configured build timeout; herrors.IsTimeoutError detects the context timeout and Hugo wraps it with a hint to raise the `timeout` config value (default 30s or 60s depending on version). It exists because content rendering is guarded by a deadline to catch template deadlocks and runaway work.
Source
Thrown at hugolib/page__content.go:825
// TODO(bep) is set in a test. Fix that.
if result.fuzzyWordCount == 0 {
result.fuzzyWordCount = (result.wordCount + 100) / 100 * 100
}
if isCJKLanguage {
result.readingTime = (result.wordCount + 500) / 501
} else {
result.readingTime = (result.wordCount + 212) / 213
}
rs.Value = result
return rs, nil
})
if err != nil {
if herrors.IsTimeoutError(err) {
err = fmt.Errorf("timed out rendering the page content. Extend the `timeout` limit in your Hugo config file: %w", err)
}
return contentPlainPlainWords{}, err
}
return v.Value, nil
}
type cachedContentScope struct {
*cachedContent
pco *pageContentOutput
scope string
}
func (c *cachedContentScope) prepareContext(ctx context.Context) context.Context {
// A regular page's shortcode etc. may be rendered by e.g. the home page,
// so we need to track any changes to this content's page.
ctx = tpl.Context.DependencyManagerScopedProvider.Set(ctx, c.pco.po.p)
// The markup scope is recursive, so if already set to a non zero value, preserve that value.View on GitHub ↗ (pinned to 8a468df065)
Solutions
- First check for self-reference: search layouts for shortcodes/partials/render hooks calling .Page.Content, .Summary, or .WordCount on the page being rendered — that's a deadlock, and raising the timeout won't fix it.
- If work is genuinely heavy, raise the limit in hugo.toml: `timeout = '120s'`.
- Cache expensive operations: use partialCached, cache remote resources, and pre-process images so repeated builds hit resources/_gen.
- On CI, persist the resources/ and cache directories between builds so image processing isn't repeated.
Example fix
# hugo.toml before # (no timeout set — 30s default) # after timeout = '120s'
Defensive patterns
Strategy: retry
Validate before calling
# hugo.toml — size the limit to the heaviest page timeout = '120s'
Try / catch
if err := h.Build(cfg); err != nil {
if strings.Contains(err.Error(), "timed out rendering") {
// raise `timeout` in config or break the recursion, then rebuild
}
return err
} Prevention
- Set `timeout` explicitly for large sites; default 30s can be tight
- A timeout often masks infinite recursion (partial rendering itself, .Content in shortcode of same page) — check for cycles first
- Cache expensive partials with partialCached
- Profile slow pages with `hugo --templateMetrics`
When it happens
Trigger: A page whose content rendering takes longer than `timeout`: huge markdown files, expensive shortcodes (resources.GetRemote, image processing of many/large images), or — very commonly — recursive template loops such as a shortcode or render hook calling .Page.Content on the same page, which deadlocks until the timeout fires.
Common situations: Sites with thousands of images processed in shortcodes; slow remote data/resource fetches during render; a partial or render-hook that references .Summary/.Content of the page currently rendering (self-reference deadlock); underpowered CI runners where builds are simply slower.
Related errors
- failed to detect target data serialization format
- unsupported transpiler %q; valid values are %q or %q
- 'paginate' configuration setting must be positive to paginat
- invalid timeout for resource %s: %w
- failed to read remote resource %q: %w
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/3f03c40c102ebdce.json.
Report an issue: GitHub ↗.