gohugoio/hugo · error
failed to parse timeout
Error message
failed to parse timeout: %s
What it means
Returned by Config.CompileConfig when the `timeout` config string cannot be parsed as a Go duration. The code first tries strconv.Atoi: if it succeeds, the number is treated as seconds and 's' is appended; otherwise it calls time.ParseDuration directly. Failure of that final parse yields this error wrapping the parse error.
Solutions
- Use a plain integer (interpreted as seconds) e.g. `timeout = 60`.
- Or use Go duration syntax e.g. `timeout = "45s"`, `timeout = "5m"`.
- Remove invalid unit words like 'sec', 'min', 'day'.
Example fix
// before timeout = "30sec" // after timeout = "30s"
Defensive patterns
Strategy: validation
Validate before calling
func validateTimeout(s string) error {
if _, err := strconv.Atoi(s); err == nil { return nil }
if _, err := time.ParseDuration(s); err == nil { return nil }
return fmt.Errorf("invalid timeout %q: use integer seconds or Go duration", s)
} Prevention
- Prefer integer seconds or Go duration strings for `timeout`.
- Add a CI lint that runs validateTimeout on the config.
- Avoid locale-specific unit words (sec/min/day).
When it happens
Trigger: Setting `timeout` in hugo.toml/yaml/json to a value that is neither a bare integer (seconds) nor a valid Go duration string (e.g. '30', '2m', '1h30m').
Common situations: Porting configs from other tools that accept human durations like '1 day' or '1d', or typos like '30sec', '5 mins', 'fast'.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- cannot convert to time.Duration
- failed to compile ignoreFiles pattern
- failed to decode filecache config
- failed to parse clock
- invalid language configuration for
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/6577fc45d50834aa.
Report an issue: GitHub.
Appendix: source
Thrown at config/allconfig/allconfig.go:279
x.StaticDir6 = nil
x.StaticDir7 = nil
x.StaticDir8 = nil
x.StaticDir9 = nil
x.StaticDir10 = nil
return &x
}
func (c *Config) CompileConfig(logger loggers.Logger) error {
var transientErr error
s := c.Timeout
if _, err := strconv.Atoi(s); err == nil {
// A number, assume seconds.
s = s + "s"
}
timeout, err := time.ParseDuration(s)
if err != nil {
return fmt.Errorf("failed to parse timeout: %s", err)
}
disabledKinds := make(map[string]bool)
for _, kind := range c.DisableKinds {
kind = strings.ToLower(kind)
if newKind := kinds.IsDeprecatedAndReplacedWith(kind); newKind != "" {
logger.Deprecatef(false, "Kind %q used in disableKinds is deprecated, use %q instead.", kind, newKind)
// Legacy config.
kind = newKind
}
if kinds.GetKindAny(kind) == "" {
logger.Warnf("Unknown kind %q in disableKinds configuration.", kind)
continue
}
disabledKinds[kind] = true
}
kindOutputFormats := make(map[string]output.Formats)
isRssDisabled := disabledKinds["rss"]
outputFormats := c.OutputFormats.ConfigView on GitHub (pinned to 52c9bd7908)