{"id":"f6eab48afbe69865","repo":"gohugoio/hugo","slug":"hmac-s-is-not-a-supported-hash-function","errorCode":null,"errorMessage":"hmac: %s is not a supported hash function","messagePattern":"hmac: (.+?) is not a supported hash function","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tpl/crypto/crypto.go","lineNumber":145,"sourceCode":"// HMAC returns a cryptographic hash that uses a key to sign a message.\nfunc (ns *Namespace) HMAC(h any, k any, m any, e ...any) (string, error) {\n\tha, err := cast.ToStringE(h)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tvar hash func() hash.Hash\n\tswitch ha {\n\tcase \"md5\":\n\t\thash = md5.New\n\tcase \"sha1\":\n\t\thash = sha1.New\n\tcase \"sha256\":\n\t\thash = sha256.New\n\tcase \"sha512\":\n\t\thash = sha512.New\n\tdefault:\n\t\treturn \"\", fmt.Errorf(\"hmac: %s is not a supported hash function\", ha)\n\t}\n\n\tmsg, err := cast.ToStringE(m)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tkey, err := cast.ToStringE(k)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tmac := hmac.New(hash, []byte(key))\n\t_, err = mac.Write([]byte(msg))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/tpl/crypto/crypto.go#L127-L163","documentation":"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.","triggerScenarios":"`{{ 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 }}`.","commonSituations":"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.","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."],"exampleFix":"<!-- before -->\n{{ hmac \"SHA-256\" $secret $payload }}\n<!-- after -->\n{{ hmac \"sha256\" $secret $payload }}","handlingStrategy":"validation","validationCode":"{{ $h := \"sha256\" }}\n{{ if in (slice \"md5\" \"sha1\" \"sha256\" \"sha512\") $h }}{{ hmac $h $secret $msg }}{{ end }}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["hugo","templates","crypto","hmac"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}