golang/go · error
crypto/rsa: prime Q is nil
Error message
crypto/rsa: prime Q is nil
What it means
Thrown by precompute() when priv.Primes[1] (prime Q) is nil, the symmetric case to prime P. Q is needed for Dq and Qinv computation. Reached only when len(priv.Primes)==2.
Source
Thrown at src/crypto/rsa/rsa.go:597
//
// It does NOT modify priv and is safe for concurrent use.
func (priv *PrivateKey) precompute() (PrecomputedValues, error) {
var precomputed PrecomputedValues
if priv.N == nil {
return precomputed, errors.New("crypto/rsa: missing public modulus")
}
if priv.D == nil {
return precomputed, errors.New("crypto/rsa: missing private exponent")
}
if len(priv.Primes) != 2 {
return priv.precomputeLegacy()
}
if priv.Primes[0] == nil {
return precomputed, errors.New("crypto/rsa: prime P is nil")
}
if priv.Primes[1] == nil {
return precomputed, errors.New("crypto/rsa: prime Q is nil")
}
// If the CRT values are already set, use them.
if priv.Precomputed.Dp != nil && priv.Precomputed.Dq != nil && priv.Precomputed.Qinv != nil {
k, err := rsa.NewPrivateKeyWithPrecomputation(priv.N.Bytes(), priv.E, priv.D.Bytes(),
priv.Primes[0].Bytes(), priv.Primes[1].Bytes(),
priv.Precomputed.Dp.Bytes(), priv.Precomputed.Dq.Bytes(), priv.Precomputed.Qinv.Bytes())
if err != nil {
return precomputed, err
}
precomputed = priv.Precomputed
precomputed.fips = k
precomputed.CRTValues = make([]CRTValue, 0)
return precomputed, nil
}
k, err := rsa.NewPrivateKey(priv.N.Bytes(), priv.E, priv.D.Bytes(),
priv.Primes[0].Bytes(), priv.Primes[1].Bytes())View on GitHub (pinned to b6b368adc5)
Solutions
- Generate keys with rsa.GenerateKey so both primes are present.
- Run priv.Validate() after parsing to detect the missing prime early.
- When assembling by hand, always set both Primes[0] and Primes[1].
- Prefer round-tripping through PKCS#1/PKCS#8 rather than field-by-field construction.
Example fix
// before
priv.Primes = []*big.Int{p, nil} // Q missing
priv.Precompute()
// after
priv.Primes = []*big.Int{p, q}
if err := priv.Validate(); err != nil { return err } Defensive patterns
Strategy: validation
Validate before calling
func checkPrimesFilled(priv *rsa.PrivateKey) error {
if len(priv.Primes) != 2 {
return fmt.Errorf("rsa: expected 2 primes, got %d", len(priv.Primes))
}
if priv.Primes[0] == nil || priv.Primes[1] == nil {
return errors.New("rsa: prime P or Q is nil")
}
return priv.Validate()
} Prevention
- Always set both Primes[0] and Primes[1] when building a key manually.
- Use rsa.GenerateKey so both primes are guaranteed present.
- Call priv.Validate() after parsing to surface a missing Q early.
- Avoid encoding schemes that drop trailing nil pointers.
When it happens
Trigger: Sign/Decrypt/Validate/Precompute on a 2-prime PrivateKey whose Primes[1]==nil. Same shape as the P case: partial construction or lossy serialization.
Common situations: Manual key construction with Primes[0] set but Primes[1] left nil; encoding schemes that drop trailing nils; copy/paste key fixtures missing Q.
Related errors
- crypto/rsa: invalid prime
- crypto/rsa: p * q != n
- crypto/rsa: invalid CRT exponent
- crypto/rsa: invalid CRT coefficient
- crypto/rsa: d does not match dP
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/89cf52218dedddfb.
Report an issue: GitHub.