micro/go-micro · error
incoming message couldn't be verified / decrypted
Error message
incoming message couldn't be verified / decrypted
What it means
NaCl box authentication failed during Decrypt. naclbox.Open verifies the Poly1305 MAC using the derived shared key before decrypting; if verification fails, nothing is returned and this error is thrown. It means the ciphertext, nonce, sender public key, or recipient private key do not form the same key pair used for encryption.
Source
Thrown at config/secrets/box/box.go:85
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
- Verify the sender's public key and your private key are the exact complementary pair used at encryption time.
- Check that the ciphertext passed to Decrypt is untouched: first 24 bytes nonce, remainder ciphertext; do not trim, prepend, or base64-decode twice.
- Re-encrypt with the current keys and retry; if key rotation occurred, distribute the new sender public key to recipients.
- Add a checksum/version prefix at the application layer so mismatched keys are detected before naclbox.Open is attempted.
Example fix
// before
raw, _ := base64.StdEncoding.DecodeString(payload)
decrypted, err := b.Decrypt(raw, secrets.WithSenderPublicKey(wrongKey))
// after
raw, err := base64.StdEncoding.DecodeString(payload)
if err != nil { return err }
if len(raw) < 24 { return errors.New("ciphertext too short") }
decrypted, err := b.Decrypt(raw, secrets.WithSenderPublicKey(correctSenderPub)) Defensive patterns
Strategy: try-catch
Validate before calling
if len(ciphertext) <= 24 {
return errors.New("ciphertext too short to contain nonce")
} Try / catch
decrypted, err := b.Decrypt(data, secrets.WithSenderPublicKey(pub))
if err != nil {
if strings.Contains(err.Error(), "couldn't be verified") {
return fmt.Errorf("decryption failed: wrong keys or corrupted data: %w", err)
}
return err
} Prevention
- Keep key pairs versioned and distributed together
- Transport ciphertext only through lossless encodings (hex/base64)
- Never mutate the encrypted payload between encrypt and decrypt
- Round-trip test after any key rotation
When it happens
Trigger: Calling box.Decrypt on ciphertext that was not encrypted with the matching sender private key / recipient public key pair; corrupted or truncated ciphertext (in shorter than 24 bytes + ciphertext, or sliced incorrectly since the first 24 bytes are the nonce); supplying the wrong SenderPublicKey.
Common situations: Key rotation where one side still uses an old key; copy-pasting keys with whitespace or wrong encoding; accidentally re-slicing or mutating the encrypted payload before decryption; a sender encrypting with a different curve/key type than box expects.
Related errors
- sender's public key bust be provided
- recepient's public key must be provided
- decryption failed (is the key set correctly?)
- no secret key is defined
AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01).
Data as JSON: /api/errors/4e08606622d15bb2.
Report an issue: GitHub.