gohugoio/hugo · critical
permalinks configuration invalid: unknown value
Error message
permalinks configuration invalid: unknown value %q for key %q for kind %q
What it means
Hugo throws this when decoding a `[permalinks.<kind>]` config table where a sub-key's value is not a string. The decoder in `decodePermalinksMap` only accepts string patterns for each section glob inside a kind table; any other type (number, list, nested map) is rejected before a `PermalinkConfig` is built. It is a hard config-load failure, not a warning.
Solutions
- Change every value inside `[permalinks.<kind>]` tables to be a single quoted string pattern, e.g. `posts = "/posts/:slug/"`.
- Validate your `hugo.toml`/`config.yaml` permalinks block against the schema: each kind table maps section-glob to string.
- Run `hugo config` to dump the parsed permalinks and confirm types render as strings.
- Remove any nested maps or arrays under kind tables; move compound rules to separate section keys.
Example fix
// hugo.toml -- before [permalinks.page] posts = 123 // after [permalinks.page] posts = "/posts/:slug/"
Defensive patterns
Strategy: validation
Validate before calling
// Pre-flight: load hugo.toml and check every [permalinks.<kind>] value is a string.
import (
"fmt"
"github.com/spf13/viper"
)
func validatePermalinksKind(cfg *viper.Viper) error {
for _, kind := range cfg.GetStringMap("permalinks") {
m, ok := kind.(map[string]any)
if !ok { continue }
for _, v := range m {
if _, ok := v.(string); !ok {
return fmt.Errorf("permalinks kind value must be string, got %T", v)
}
}
}
return nil
} Prevention
- Lint hugo.toml in CI with a schema checker before `hugo` runs.
- Quote all permalink pattern strings in TOML/YAML.
- Keep a single canonical permalinks form (prefer `[permalinks.kind]`).
When it happens
Trigger: Calling config load / `hugo` build with a `permalinks` table like `[permalinks.page]` where an entry value is non-string, e.g. `posts = 123`, `posts = ["a","b"]`, or `posts = { pattern = "/x/" }`. Reached via the `hmaps.Params` branch of the type switch at permalinks.go:585-594.
Common situations: YAML/TOML indentation slip making a value a table instead of a string; copy-pasting a numeric weight into the pattern slot; mixing the old flat `permalinks.key = 'pattern'` form with the new `[permalinks.kind]` form incorrectly; upgrading from an older Hugo that tolerated looser typing.
Related errors
- permalinks configuration invalid: unknown value
- config needs a filename
- invalid log level: , must be one of debug, warn, info or…
- language not found
- permalink attribute not recognised
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/edadcc5ad3f7dc98.
Report an issue: GitHub.
Appendix: source
Thrown at resources/page/permalinks.go:592
configs = append(configs,
PermalinkConfig{Target: PageMatcher{Kind: kinds.KindPage, Path: sectionToPathGlob(k)}, Pattern: v},
PermalinkConfig{Target: PageMatcher{Kind: kinds.KindTerm, Path: sectionToPathGlob(k)}, Pattern: v},
)
case hmaps.Params:
// [permalinks.kind]
// section = '...'
if !hstrings.InSlice(permalinksKindsSupport, k) {
return nil, fmt.Errorf("permalinks configuration not supported for kind %q, supported kinds are %v", k, permalinksKindsSupport)
}
for k2, v2 := range v {
switch v2 := v2.(type) {
case string:
configs = append(configs,
PermalinkConfig{Target: PageMatcher{Kind: k, Path: sectionToPathGlob(k2)}, Pattern: v2},
)
default:
return nil, fmt.Errorf("permalinks configuration invalid: unknown value %q for key %q for kind %q", v2, k2, k)
}
}
default:
return nil, fmt.Errorf("permalinks configuration invalid: unknown value %q for key %q", v, k)
}
}
return configs, nil
}
View on GitHub (pinned to 52c9bd7908)