gohugoio/hugo · error
hmac: %s is not a supported hash function
Error message
hmac: %s is not a supported hash function
What it means
Hugo's `hmac` template function only supports `md5`, `sha1`, `sha256`, and `sha512` as the hash-function name (its first argument). Note this list differs from `crypto.Hash`: sha384 is not available for HMAC. Any other name returns this error before the MAC is computed.
Source
Thrown at tpl/crypto/crypto.go:145
// HMAC returns a cryptographic hash that uses a key to sign a message.
func (ns *Namespace) HMAC(h any, k any, m any, e ...any) (string, error) {
ha, err := cast.ToStringE(h)
if err != nil {
return "", err
}
var hash func() hash.Hash
switch ha {
case "md5":
hash = md5.New
case "sha1":
hash = sha1.New
case "sha256":
hash = sha256.New
case "sha512":
hash = sha512.New
default:
return "", fmt.Errorf("hmac: %s is not a supported hash function", ha)
}
msg, err := cast.ToStringE(m)
if err != nil {
return "", err
}
key, err := cast.ToStringE(k)
if err != nil {
return "", err
}
mac := hmac.New(hash, []byte(key))
_, err = mac.Write([]byte(msg))
if err != nil {
return "", err
}
View on GitHub ↗ (pinned to 8a468df065)
Solutions
- Use one of the exact lowercase names: md5, sha1, sha256, or sha512.
- Check the argument order: `hmac HASH KEY MESSAGE` — the hash name is the first argument, not the key.
- If you need sha384, it isn't supported by hmac; pick sha256 or sha512, or handle signing outside Hugo.
Example fix
<!-- before -->
{{ hmac "SHA-256" $secret $payload }}
<!-- after -->
{{ hmac "sha256" $secret $payload }} Defensive patterns
Strategy: validation
Validate before calling
{{ $h := "sha256" }}
{{ if in (slice "md5" "sha1" "sha256" "sha512") $h }}{{ hmac $h $secret $msg }}{{ end }} Prevention
- Use only supported hash names with hmac: md5, sha1, sha256, sha512
- Prefer a hard-coded literal algorithm over a computed one
- Validate any config-driven hash name at template top with errorf on mismatch
When it happens
Trigger: `{{ hmac "sha384" $key $msg }}` (sha384 works in crypto.Hash but not hmac); `{{ hmac "SHA256" $key $msg }}` (case-sensitive); passing the key first by mistake so the key string is treated as the hash name: `{{ hmac $key "sha256" $msg }}`.
Common situations: Building webhook or API-request signatures (AWS SigV4, Slack, GitHub) and using an uppercase or hyphenated algorithm name from the provider's docs; wrong argument order — hmac is HASH, KEY, MESSAGE [, ENCODING]; assuming sha384 support because crypto.Hash has it.
Related errors
- crypto.Hash: expected 1 or 2 arguments, got %d
- crypto.Hash: %q is not a supported hash algorithm
- %q is not a supported encoding method
- error building site: %w
- failed to detect format from content
AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31).
Data as JSON: /data/errors/f6eab48afbe69865.json.
Report an issue: GitHub ↗.