{"record":{"id":"662dafddcc0fe776","repo":"golang/go","slug":"crypto-rsa-missing-primes","errorCode":null,"errorMessage":"crypto/rsa: missing primes","messagePattern":"crypto/rsa: missing primes","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/rsa/rsa.go","lineNumber":244,"sourceCode":"}\n\n// CRTValue contains the precomputed Chinese remainder theorem values.\ntype CRTValue struct {\n\tExp   *big.Int // D mod (prime-1).\n\tCoeff *big.Int // R·Coeff ≡ 1 mod Prime.\n\tR     *big.Int // product of primes prior to this (inc p and q).\n}\n\n// Validate performs basic sanity checks on the key.\n// It returns nil if the key is valid, or else an error describing a problem.\n//\n// It runs faster on valid keys if run after [PrivateKey.Precompute].\nfunc (priv *PrivateKey) Validate() error {\n\t// We can operate on keys based on d alone, but they can't be encoded with\n\t// [crypto/x509.MarshalPKCS1PrivateKey], which unfortunately doesn't return\n\t// an error, so we need to reject them here.\n\tif len(priv.Primes) < 2 {\n\t\treturn errors.New(\"crypto/rsa: missing primes\")\n\t}\n\t// If Precomputed.fips is set and consistent, then the key has been\n\t// validated by [rsa.NewPrivateKey] or [rsa.NewPrivateKeyWithoutCRT].\n\tif priv.precomputedIsConsistent() {\n\t\treturn nil\n\t}\n\tif priv.Precomputed.fips != nil {\n\t\treturn errors.New(\"crypto/rsa: precomputed values are inconsistent with the key\")\n\t}\n\t_, err := priv.precompute()\n\treturn err\n}\n\nfunc (priv *PrivateKey) precomputedIsConsistent() bool {\n\tif priv.Precomputed.fips == nil {\n\t\treturn false\n\t}\n\tN, e, d, P, Q, dP, dQ, qInv := priv.Precomputed.fips.Export()","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/rsa/rsa.go#L226-L262","documentation":"Returned by PrivateKey.Validate when len(priv.Primes) < 2. The RSA implementation requires at least the two classical primes p and q; a key that only carries D (a 'CRT-less' or d-only key) cannot be validated by this routine because the CRT-based consistency checks need p and q. The doc comment also notes that such keys cannot be encoded by x509.MarshalPKCS1PrivateKey, so they are rejected early.","triggerScenarios":"Build a PrivateKey struct with D set but Primes empty or with one prime; call Validate() (directly or transitively via Precompute then Validate) on that key; partially parse a key file that omitted primes.","commonSituations":"Loading JWK / PEM that only exposes 'd' (some cloud KMS export formats omit CRT params); constructing a key in tests for sign-only use without realizing Validate needs both primes; deserializing a corrupt key.","solutions":["Use rsa.NewPrivateKey / NewPrivateKeyWithoutCRT (FIPS module) or x509.ParsePKCS1PrivateKey to build keys — they reject incomplete inputs upstream with clearer errors.","If you only have N, e, d, obtain p and q from the source (re-export the full CRT material from your KMS/HSM).","Skip Validate() only if you can guarantee correctness by other means and never need MarshalPKCS1PrivateKey."],"exampleFix":"// before: key reconstructed with only D\npriv := &rsa.PrivateKey{\n    PublicKey: rsa.PublicKey{N: n, E: e},\n    D:         d,\n}\nerr := priv.Validate() // err: missing primes\n\n// after: include primes\npriv.Primes = []*big.Int{p, q}\nerr := priv.Validate()","handlingStrategy":"validation","validationCode":"if priv == nil || len(priv.Primes) < 2 {\n    return errors.New(\"RSA private key must include at least two primes\")\n}\nreturn priv.Validate()","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Parse keys with x509.ParsePKCS1PrivateKey / ParsePKCS8PrivateKey rather than building literals.","Treat d-only keys as unsupported; request full CRT material from the KMS.","Run Validate() at load time, not lazily during request handling."],"tags":["rsa","key-validation","crypto","api-misuse"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}