micro/go-micro · error
sender's public key bust be provided
Error message
sender's public key bust be provided
What it means
This error comes from the NaCl box crypto secret backend during Decrypt. NaCl box decryption requires the sender's public key (to derive the shared secret against the recipient's private key), and it must be exactly 32 bytes (keyLength). The library throws this when no sender public key was supplied via DecryptOption, or the supplied key has the wrong length.
Source
Thrown at config/secrets/box/box.go:77
return []byte{}, errors.New("recepient's public key must be provided")
}
var recipientPublicKey [keyLength]byte
copy(recipientPublicKey[:], options.RecipientPublicKey)
var nonce [24]byte
if _, err := rand.Reader.Read(nonce[:]); err != nil {
return []byte{}, errors.Wrap(err, "couldn't obtain a random nonce from crypto/rand")
}
return naclbox.Seal(nonce[:], in, &nonce, &recipientPublicKey, &b.privateKey), nil
}
// Decrypt Decrypts a message with the receiver's private key and the sender's public key.
func (b *box) Decrypt(in []byte, opts ...secrets.DecryptOption) ([]byte, error) {
var options secrets.DecryptOptions
for _, o := range opts {
o(&options)
}
if len(options.SenderPublicKey) != keyLength {
return []byte{}, errors.New("sender's public key bust be provided")
}
var nonce [24]byte
var senderPublicKey [32]byte
copy(nonce[:], in[:24])
copy(senderPublicKey[:], options.SenderPublicKey)
decrypted, ok := naclbox.Open(nil, in[24:], &nonce, &senderPublicKey, &b.privateKey)
if !ok {
return []byte{}, errors.New("incoming message couldn't be verified / decrypted")
}
return decrypted, nil
}
View on GitHub (pinned to 24529f1404)
Solutions
- Pass a DecryptOption that sets SenderPublicKey to the peer's 32-byte public key, e.g. secrets.WithSenderPublicKey(pub) (use the exact option name from the secrets package).
- Verify the key is exactly 32 bytes: len(pub) == 32; decode from hex/base64 with the correct function and check for errors before use.
- Confirm you are using the same key pair that the sender encrypted with; box decryption fails even with keys of the right length if the pair is mismatched.
- Ensure your DecryptOptions are actually applied — the variadic opts must be passed through to Decrypt, not dropped by an intermediate wrapper.
Example fix
// before decrypted, err := b.Decrypt(data) // after pub, _ := hex.DecodeString(senderPubHex) // must yield 32 bytes decrypted, err := b.Decrypt(data, secrets.WithSenderPublicKey(pub))
Defensive patterns
Strategy: validation
Validate before calling
if len(senderPub) != 32 {
return fmt.Errorf("sender public key must be 32 bytes, got %d", len(senderPub))
} Type guard
func validSenderKey(pub []byte) bool { return len(pub) == 32 } Prevention
- Store sender public keys as fixed [32]byte or validate length right after decoding
- Always pass the DecryptOption explicitly in a small wrapper around box.Decrypt
- Test encryption/decryption round-trips in CI with the real key pair
When it happens
Trigger: Calling box.Decrypt(data) without passing a secrets.DecryptOption that sets SenderPublicKey, or passing a SenderPublicKey slice that is empty or not exactly 32 bytes long.
Common situations: Forgetting to configure the sender's public key when sharing encrypted config values between services; encoding the sender key from a hex/base64 string and trimming it incorrectly; using a key from a different crypto scheme (e.g. a 44-byte or 65-byte key) that doesn't match NaCl box's 32-byte requirement.
Related errors
- incoming message couldn't be verified / decrypted
- recepient's public key must be provided
- decryption failed (is the key set correctly?)
- no values
- <joined load errors>
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/d82b87276633784c.
Report an issue: GitHub.