slackhq/nebula · error
got a key of %d bytes, expected %d
Error message
got a key of %d bytes, expected %d
What it means
Test() performed a self-ECDH (DeriveNoise with the node's own public key) and the resulting shared secret length did not equal NoiseKeySize (32 bytes). The library throws this because a derive operation returning a different-size secret means the key or HSM cannot produce valid Noise material.
Source
Thrown at pkclient/pkclient.go:84
switch t := e.(type) {
case *ecdsa.PublicKey:
return ecKeyToArray(e.(*ecdsa.PublicKey)), nil
default:
return nil, fmt.Errorf("unknown public key type: %T", t)
}
}
func (c *PKClient) Test() error {
pub, err := c.GetPubKey()
if err != nil {
return fmt.Errorf("failed to get public key: %w", err)
}
out, err := c.DeriveNoise(pub) //do an ECDH with ourselves as a quick test
if err != nil {
return err
}
if len(out) != NoiseKeySize {
return fmt.Errorf("got a key of %d bytes, expected %d", len(out), NoiseKeySize)
}
return nil
}
View on GitHub (pinned to dd8f660c0a)
Solutions
- Provision/verify the key is EC P-256 (prime256v1) specifically
- Check the HSM vendor's derive output format; left-pad to 32 bytes if a firmware quirk strips leading zeros
- Update the HSM firmware/vendor PKCS#11 library
- Confirm CKA_EC_PARAMS is the prime256v1 OID
- Test the same key with a minimal PKCS#11 derive script to see raw length
Example fix
// before pkcs11-tool --keypairgen --key-type EC:secp384r1 --usage-derive // after pkcs11-tool --keypairgen --key-type EC:prime256v1 --usage-derive
Defensive patterns
Strategy: validation
Validate before calling
// ensure curve is P-256 before deriving
params, _ := session.GetAttributeValue(key, []*pkcs11.Attribute{
pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, nil),
})
// prime256v1 OID encoding: 06 08 2A 86 48 CE 3D 03 01 07
if !bytes.Equal(params[0].Value, []byte{0x06,0x08,0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07}) {
return errors.New("HSM EC key is not P-256")
} Try / catch
if err := client.Test(); err != nil {
if strings.Contains(err.Error(), "got a key of") {
return fmt.Errorf("HSM derive output incompatible; use P-256 key/vendor fix: %w", err)
}
return err
} Prevention
- Provision only P-256 (prime256v1) derive keys
- Test a fresh key with the HSM before production
- Check vendor docs for derive output padding quirks
- Keep vendor PKCS#11 middleware updated
When it happens
Trigger: Calling Test() when session.DeriveNoise succeeds but returns byte length != NoiseKeySize — e.g. the HSM derives raw X coordinate padded differently, or the key is not a P-256 EC key.
Common situations: HSMs that return the derived secret with leading-zero padding stripped; non-P-256 curves (P-384/P-521) producing 48/66-byte secrets; non-EC keys that still expose a derive mechanism.
Related errors
- unable to unmarshal pubkey: %w
- got an empty secret key
- notImplemented
- error while creating PKCS#11 client: %w
- error while getting public key with PKCS#11: %w
AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03).
Data as JSON: /api/errors/bd9c626e025e23d9.
Report an issue: GitHub.