{"record":{"id":"89cf52218dedddfb","repo":"golang/go","slug":"crypto-rsa-prime-q-is-nil","errorCode":null,"errorMessage":"crypto/rsa: prime Q is nil","messagePattern":"crypto/rsa: prime Q is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/rsa/rsa.go","lineNumber":597,"sourceCode":"//\n// It does NOT modify priv and is safe for concurrent use.\nfunc (priv *PrivateKey) precompute() (PrecomputedValues, error) {\n\tvar precomputed PrecomputedValues\n\n\tif priv.N == nil {\n\t\treturn precomputed, errors.New(\"crypto/rsa: missing public modulus\")\n\t}\n\tif priv.D == nil {\n\t\treturn precomputed, errors.New(\"crypto/rsa: missing private exponent\")\n\t}\n\tif len(priv.Primes) != 2 {\n\t\treturn priv.precomputeLegacy()\n\t}\n\tif priv.Primes[0] == nil {\n\t\treturn precomputed, errors.New(\"crypto/rsa: prime P is nil\")\n\t}\n\tif priv.Primes[1] == nil {\n\t\treturn precomputed, errors.New(\"crypto/rsa: prime Q is nil\")\n\t}\n\n\t// If the CRT values are already set, use them.\n\tif priv.Precomputed.Dp != nil && priv.Precomputed.Dq != nil && priv.Precomputed.Qinv != nil {\n\t\tk, err := rsa.NewPrivateKeyWithPrecomputation(priv.N.Bytes(), priv.E, priv.D.Bytes(),\n\t\t\tpriv.Primes[0].Bytes(), priv.Primes[1].Bytes(),\n\t\t\tpriv.Precomputed.Dp.Bytes(), priv.Precomputed.Dq.Bytes(), priv.Precomputed.Qinv.Bytes())\n\t\tif err != nil {\n\t\t\treturn precomputed, err\n\t\t}\n\t\tprecomputed = priv.Precomputed\n\t\tprecomputed.fips = k\n\t\tprecomputed.CRTValues = make([]CRTValue, 0)\n\t\treturn precomputed, nil\n\t}\n\n\tk, err := rsa.NewPrivateKey(priv.N.Bytes(), priv.E, priv.D.Bytes(),\n\t\tpriv.Primes[0].Bytes(), priv.Primes[1].Bytes())","sourceCodeStart":579,"sourceCodeEnd":615,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/rsa/rsa.go#L579-L615","documentation":"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.","triggerScenarios":"Sign/Decrypt/Validate/Precompute on a 2-prime PrivateKey whose Primes[1]==nil. Same shape as the P case: partial construction or lossy serialization.","commonSituations":"Manual key construction with Primes[0] set but Primes[1] left nil; encoding schemes that drop trailing nils; copy/paste key fixtures missing Q.","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."],"exampleFix":"// before\npriv.Primes = []*big.Int{p, nil} // Q missing\npriv.Precompute()\n\n// after\npriv.Primes = []*big.Int{p, q}\nif err := priv.Validate(); err != nil { return err }","handlingStrategy":"validation","validationCode":"func checkPrimesFilled(priv *rsa.PrivateKey) error {\n    if len(priv.Primes) != 2 {\n        return fmt.Errorf(\"rsa: expected 2 primes, got %d\", len(priv.Primes))\n    }\n    if priv.Primes[0] == nil || priv.Primes[1] == nil {\n        return errors.New(\"rsa: prime P or Q is nil\")\n    }\n    return priv.Validate()\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["crypto","rsa","key-validation","go"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}