gohugoio/hugo · critical
failed to load config: %v
Error message
failed to load config: %v
What it means
Produced by the deferred recover() at the top of LoadConfig: if anything in the config-loading pipeline panics, the panic value is converted into this error (with %v, so no wrapped cause chain) and the stack is printed via debug.PrintStack. It is a catch-all guard so a bug or pathological config crashes with a diagnosable error instead of an unrecovered panic.
Source
Thrown at config/allconfig/load.go:48
"github.com/gohugoio/hugo/common/loggers"
"github.com/gohugoio/hugo/common/paths"
"github.com/gohugoio/hugo/common/types"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/helpers"
hglob "github.com/gohugoio/hugo/hugofs/hglob"
"github.com/gohugoio/hugo/modules"
"github.com/gohugoio/hugo/modules/npm"
"github.com/gohugoio/hugo/parser/metadecoders"
"github.com/spf13/afero"
)
//lint:ignore ST1005 end user message.
var ErrNoConfigFile = errors.New("Unable to locate config file or config directory. Perhaps you need to create a new project.\n Run `hugo help new` for details.\n")
func LoadConfig(d ConfigSourceDescriptor) (configs *Configs, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("failed to load config: %v", r)
debug.PrintStack()
}
}()
if len(d.Environ) == 0 && !hugo.IsRunningAsTest() {
d.Environ = os.Environ()
}
if d.Logger == nil {
d.Logger = loggers.NewDefault()
}
l := &configLoader{ConfigSourceDescriptor: d, cfg: config.New()}
// Make sure we always do this, even in error situations,
// as we have commands (e.g. "hugo mod init") that will
// use a partial configuration to do its job.
defer l.deleteMergeStrategies()
res, _, err := l.loadConfigMain(d)View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Read the printed stack trace — it names the exact decoder/function that panicked; the message alone only says loading failed.
- Bisect your config: comment out recently changed sections until the panic disappears to find the offending value.
- Upgrade to the latest Hugo release in case the panic is a fixed bug; if it reproduces on latest, report it at github.com/gohugoio/hugo/issues with the stack trace and a minimal config.
- Check for type mismatches in config (e.g. a string where a table is expected) in the section the stack trace implicates.
Defensive patterns
Strategy: try-catch
Try / catch
conf, err := allconfig.LoadConfig(opts)
if err != nil {
var fe herrors.FileError
if errors.As(err, &fe) {
log.Printf("config error at %s: %v", fe.Position(), err)
}
return fmt.Errorf("hugo config load: %w", err)
} Prevention
- Note this wrapper uses %v, not %w — don't rely on unwrapping through it; match on the file-error type or message from the inner loader instead
- Lint config files (TOML/YAML syntax) in CI before running Hugo
- Keep configDir (config/_default, config/production) layouts consistent so merge errors don't surface only in one environment
When it happens
Trigger: Any panic during config loading — a nil-pointer dereference or index-out-of-range in a config decoder, a panicking template/module hook, or config values of unexpected types that a decoder asserts on without checking. The accompanying stack trace on stderr identifies the real site.
Common situations: Hitting a Hugo bug with an unusual config shape (a scalar where a map is expected in an obscure section); building with a mismatched or corrupted module cache; regressions in a freshly upgraded Hugo version.
Related errors
- errConfigNotSet
- max depth exceeded
- failed to compile whitelist pattern %q: %w
- failed to init config: %w
- no filesystem provided
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/7c898951b34eb9c6.json.
Report an issue: GitHub ↗.