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

  1. 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).
  2. Verify the key is exactly 32 bytes: len(pub) == 32; decode from hex/base64 with the correct function and check for errors before use.
  3. 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.
  4. 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

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


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/d82b87276633784c. Report an issue: GitHub.