OpenNHP/opennhp · error
failed to create HMAC hash
Error message
failed to create HMAC hash: %w
What it means
Immediately after the chain hash, createPacketParserData initializes the HMAC hash (HmacHash0) used for per-packet MAC verification; NewHash failed for the same class of reasons as the chain-hash error — the CipherSuite's HashType is unsupported or the hash backend is broken. Packet processing aborts before HMAC checking, so no message is decrypted or dispatched.
Solutions
- Log ppd.Ciphers.HashType and ppd.CipherScheme at failure to identify the unsupported value.
- Rebuild against a known-good crypto dependency version where SM3/BLAKE2s instantiate correctly.
- Ensure all CipherSuites are produced by NewCipherSuite rather than constructed literally.
- Add boot-time smoke tests calling NewHash for each supported scheme.
Example fix
// before
testSuite := &core.CipherSuite{HashType: 0xFF}
_ , err := d.CreatePacketParserData(pd) // failed to create HMAC hash
// after
testSuite := core.NewCipherSuite(common.CIPHER_SCHEME_GMSM)
_, err := d.CreatePacketParserData(pd) Defensive patterns
Strategy: try-catch
Validate before calling
if _, err := core.NewHash(suite.HashType); err != nil {
return fmt.Errorf("hmac hash unavailable for hashType %d", suite.HashType)
} Try / catch
ppd.hmacHash, err = NewHash(ppd.Ciphers.HashType)
if err != nil {
log.Error("hmac hash init failed hashType=%d: %v", ppd.Ciphers.HashType, err)
return nil, fmt.Errorf("failed to create HMAC hash: %w", err)
} Prevention
- Shared root cause with chain-hash init — apply the same startup smoke tests.
- Never hand-populate CipherSuite fields.
- Keep hash implementations compiled into all build variants.
- Alert on first occurrence; it indicates a backend/build problem, not bad traffic.
When it happens
Trigger: Same as the chain-hash failure: invalid HashType reaching NewHash from NewCipherSuite during PacketToMsg/parseRKNOnServer, or a failing hash backend; typically only after customizing cipher suites or upgrading the crypto dependency.
Common situations: Custom crypto builds; dependency regressions; hand-constructed CipherSuites in tests or plugins; practically never in stock deployments where both schemes use always-available hashes.
Related errors
- extractInitiatorStaticPubKey: init hash
- failed to create chain hash
- invalid input key
- missing remote peer public key
- failed to create HMAC hash
AI-assisted analysis of OpenNHP/opennhp@6e04ca5ff0 (2026-09-07).
Data as JSON: /api/errors/fddb85b85fb1f234.
Report an issue: GitHub.
Appendix: source
Thrown at nhp/core/responder.go:314
}
// init chain hash -> ChainHash0
ppd.chainHash, err = NewHash(ppd.Ciphers.HashType)
if err != nil {
return nil, fmt.Errorf("failed to create chain hash: %w", err)
}
ppd.chainHash.Write([]byte(InitialHashString))
// init chain key -> ChainKey0
ppd.noise.HashType = ppd.Ciphers.HashType
ppd.noise.MixKey(&ppd.chainKey, ppd.chainHash.Sum(nil), []byte(InitialChainKeyString))
ppd.HeaderType, ppd.BodySize = ppd.header.TypeAndPayloadSize()
// init hmac hash -> HmacHash0
ppd.hmacHash, err = NewHash(ppd.Ciphers.HashType)
if err != nil {
return nil, fmt.Errorf("failed to create HMAC hash: %w", err)
}
ppd.hmacHash.Write([]byte(InitialHashString))
// evolve hmac hash HmacHash0 -> HmacHash1
ppd.hmacHash.Write(ppd.deviceEcdh.PublicKey())
// check hmac
if ppd.device.deviceType == NHP_SERVER {
// server overload handling
overload := ppd.device.IsOverload()
if overload {
// overload, further discard unwanted packet type
ppd.Overload = true
if !ppd.IsAllowedAtOverload() {
log.Critical("discard packet type %d due to overload", ppd.HeaderType)
err = ErrServerOverload
return
}View on GitHub (pinned to 6e04ca5ff0)