{"record":{"id":"4cd97f8c021c6f37","repo":"golang/go","slug":"crypto-rsa-public-key-missing-n","errorCode":null,"errorMessage":"crypto/rsa: public key missing N","messagePattern":"crypto/rsa: public key missing N","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/rsa/fips.go","lineNumber":441,"sourceCode":"\t\treturn ErrDecryption\n\tcase rsa.ErrVerification:\n\t\treturn ErrVerification\n\tcase rsa.ErrMessageTooLong:\n\t\treturn ErrMessageTooLong\n\t}\n\treturn err\n}\n\nfunc fipsError2[T any](x T, err error) (T, error) {\n\treturn x, fipsError(err)\n}\n\nfunc checkFIPS140OnlyPublicKey(pub *PublicKey) error {\n\tif !fips140only.Enforced() {\n\t\treturn nil\n\t}\n\tif pub.N == nil {\n\t\treturn errors.New(\"crypto/rsa: public key missing N\")\n\t}\n\tif pub.N.BitLen() < 2048 {\n\t\treturn errors.New(\"crypto/rsa: use of keys smaller than 2048 bits is not allowed in FIPS 140-only mode\")\n\t}\n\tif pub.N.BitLen()%2 == 1 {\n\t\treturn errors.New(\"crypto/rsa: use of keys with odd size is not allowed in FIPS 140-only mode\")\n\t}\n\tif pub.E <= 1<<16 {\n\t\treturn errors.New(\"crypto/rsa: use of public exponent <= 2¹⁶ is not allowed in FIPS 140-only mode\")\n\t}\n\tif pub.E&1 == 0 {\n\t\treturn errors.New(\"crypto/rsa: use of even public exponent is not allowed in FIPS 140-only mode\")\n\t}\n\treturn nil\n}\n\nfunc checkFIPS140OnlyPrivateKey(priv *PrivateKey) error {\n\tif !fips140only.Enforced() {","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/rsa/fips.go#L423-L459","documentation":"Thrown by checkFIPS140OnlyPublicKey when fips140only.Enforced() and pub.N == nil. The public key's modulus is not set, meaning the key struct is uninitialized (zero-value) or was incompletely parsed. This is the first key-validity gate in FIPS-only mode; it fires before size/exponent checks.","triggerScenarios":"Passing a freshly-declared &rsa.PublicKey{} (N is nil) to any FIPS-guarded RSA op. Parsing a malformed or truncated key (e.g. x509.ParsePKIXPublicKey on corrupt bytes returning a partial struct). Using a key literal without setting N.","commonSituations":"Key-loading code that ignores a parse error and proceeds with a zero-value key. Conditional key initialization where a branch leaves N unset. Test fixtures with placeholder keys.","solutions":["Load the key via x509.ParsePKIXPublicKey / x509.ParsePKCS1PublicKey and check the returned error before use.","Add a nil check: if pub.N == nil { return errors.New(\"key not loaded\") } before any RSA call.","Ensure the key-parsing code path always runs on startup and fails fast on malformed input."],"exampleFix":"// before\nvar pub rsa.PublicKey // N is nil\nct, err := rsa.EncryptOAEP(h, rand.Reader, &pub, msg, nil)\n\n// after\npubAny, err := x509.ParsePKIXPublicKey(keyDER)\nif err != nil { return err }\npub := pubAny.(*rsa.PublicKey)\nct, err := rsa.EncryptOAEP(h, rand.Reader, pub, msg, nil)","handlingStrategy":"validation","validationCode":"if pub == nil || pub.N == nil {\n    return errors.New(\"public key is nil or missing modulus N\")\n}\n// proceed with RSA operations","typeGuard":"func publicKeyHasN(pub *rsa.PublicKey) bool {\n    return pub != nil && pub.N != nil\n}","tryCatchPattern":null,"preventionTips":["Always check the error from x509.ParsePKIXPublicKey / ParsePKCS1PublicKey before using the key.","Add a startup health check that validates all loaded keys have non-nil N.","Never pass a zero-value rsa.PublicKey to crypto operations."],"tags":["crypto","rsa","fips","key-validation"],"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:17:08.281Z"}