golang/go · error
crypto/rsa: missing public modulus
Error message
crypto/rsa: missing public modulus
What it means
Returned by checkPublicKeySize when k.N is nil. checkPublicKeySize runs at the entry of every public operation that uses a PublicKey (EncryptPKCS1v15, EncryptOAEP, VerifyPKCS1v15, VerifyPSS, SignJSON callers via the encrypt/verify wrappers). A nil N means the key was never populated — there is no modulus to operate on, so the operation cannot proceed.
Source
Thrown at src/crypto/rsa/rsa.go:303
// rsa1024min is a GODEBUG that re-enables weak RSA keys if set to "0".
// See https://go.dev/issue/68762.
var rsa1024min = godebug.New("rsa1024min")
func checkKeySize(size int) error {
if size >= 1024 {
return nil
}
if rsa1024min.Value() == "0" {
rsa1024min.IncNonDefault()
return nil
}
return fmt.Errorf("crypto/rsa: %d-bit keys are insecure (see https://go.dev/pkg/crypto/rsa#hdr-Minimum_key_size)", size)
}
func checkPublicKeySize(k *PublicKey) error {
if k.N == nil {
return errors.New("crypto/rsa: missing public modulus")
}
return checkKeySize(k.N.BitLen())
}
// GenerateKey generates a random RSA private key of the given bit size.
//
// If bits is less than 1024, [GenerateKey] returns an error. See the "[Minimum
// key size]" section for further details.
//
// Since Go 1.26, a secure source of random bytes is always used, and the Reader is
// ignored unless GODEBUG=cryptocustomrand=1 is set. This setting will be removed
// in a future Go release. Instead, use [testing/cryptotest.SetGlobalRandom].
//
// [Minimum key size]: https://pkg.go.dev/crypto/rsa#hdr-Minimum_key_size
func GenerateKey(random io.Reader, bits int) (*PrivateKey, error) {
if err := checkKeySize(bits); err != nil {
return nil, err
}View on GitHub (pinned to b6b368adc5)
Solutions
- Ensure the *rsa.PublicKey was produced by x509.ParsePKIXPublicKey / ParsePKCS1PublicKey and that the input was actually RSA.
- Add a nil check: if pub == nil || pub.N == nil { return ErrInvalidKey }.
- Construct public-key variables only via parsing helpers or rsa.PrivateKey.PublicKey, never by hand.
Example fix
// before
var pub rsa.PublicKey // zero value, N == nil
ct, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, &pub, msg, nil)
// after
pubAny, err := x509.ParsePKIXPublicKey(der)
if err != nil { return err }
pub, ok := pubAny.(*rsa.PublicKey)
if !ok || pub.N == nil { return errors.New("not an RSA public key") }
ct, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, pub, msg, nil) Defensive patterns
Strategy: validation
Validate before calling
if pub == nil || pub.N == nil {
return errors.New("RSA public key is missing modulus")
}
return nil // then call EncryptOAEP/Verify* Type guard
func isUsableRSAPublicKey(pub *rsa.PublicKey) bool {
return pub != nil && pub.N != nil && pub.N.Sign() > 0 && pub.E > 0
} Prevention
- Parse public keys with x509.ParsePKIXPublicKey and type-assert *rsa.PublicKey.
- Add nil/sign checks in a shared wrapper around Encrypt*/Verify*.
- Avoid zero-value rsa.PublicKey literals.
When it happens
Trigger: Use a zero-value rsa.PublicKey{}; call rsa.EncryptOAEP on a *rsa.PublicKey whose N was not assigned; parse a key with x509.ParsePKIXPublicKey but type-asserted to *rsa.PublicKey when the underlying algorithm was ECDSA (N stays nil).
Common situations: Default struct initialization in tests; wrong type assertion after parsing (e.g. *rsa.PublicKey vs *ecdsa.PublicKey); copying only E but not N from a parsed key.
Related errors
- crypto/rsa: public exponent is even
- crypto/rsa: public exponent too large
- crypto/rsa: invalid PSS salt length
- crypto/rsa: missing public modulus
- crypto/rsa: public modulus is even
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/f87588b1f9f555ee.
Report an issue: GitHub.