{"record":{"id":"8752d2040a43960c","repo":"golang/go","slug":"crypto-rsa-invalid-options-for-decrypt","errorCode":null,"errorMessage":"crypto/rsa: invalid options for Decrypt","messagePattern":"crypto/rsa: invalid options for Decrypt","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/crypto/rsa/rsa.go","lineNumber":206,"sourceCode":"\t\t\treturn decryptOAEP(opts.Hash.New(), opts.MGFHash.New(), priv, ciphertext, opts.Label)\n\t\t}\n\n\tcase *PKCS1v15DecryptOptions:\n\t\tif l := opts.SessionKeyLen; l > 0 {\n\t\t\tplaintext = make([]byte, l)\n\t\t\tif _, err := io.ReadFull(rand, plaintext); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\tif err := DecryptPKCS1v15SessionKey(rand, priv, ciphertext, plaintext); err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\treturn plaintext, nil\n\t\t} else {\n\t\t\treturn DecryptPKCS1v15(rand, priv, ciphertext)\n\t\t}\n\n\tdefault:\n\t\treturn nil, errors.New(\"crypto/rsa: invalid options for Decrypt\")\n\t}\n}\n\ntype PrecomputedValues struct {\n\tDp, Dq *big.Int // D mod (P-1) (or mod Q-1)\n\tQinv   *big.Int // Q^-1 mod P\n\n\t// CRTValues is used for the 3rd and subsequent primes. Due to a\n\t// historical accident, the CRT for the first two primes is handled\n\t// differently in PKCS #1 and interoperability is sufficiently\n\t// important that we mirror this.\n\t//\n\t// Deprecated: These values are still filled in by Precompute for\n\t// backwards compatibility but are not used. Multi-prime RSA is very rare,\n\t// and is implemented by this package without CRT optimizations to limit\n\t// complexity.\n\tCRTValues []CRTValue\n","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/crypto/rsa/rsa.go#L188-L224","documentation":"Returned by PrivateKey.Decrypt when opts is not nil and is not one of the two recognized concrete types (*rsa.OAEPOptions or *rsa.PKCS1v15DecryptOptions). The crypto.DecrypterOpts interface allows arbitrary types, but this RSA implementation only supports those two; anything else falls into the default switch case. Note it is the pointer types that are matched — passing a non-pointer OAEPOptions value will also hit this path.","triggerScenarios":"Pass a custom type implementing crypto.DecrypterOpts to priv.Decrypt; pass rsa.OAEPOptions{} by value instead of &rsa.OAEPOptions{}; pass an interface wrapping a third-party options struct.","commonSituations":"Generic crypto code that accepts crypto.DecrypterOpts from a caller and forwards it without narrowing; copy-paste mistake omitting the & on OAEPOptions.","solutions":["Pass &rsa.OAEPOptions{...} or &rsa.PKCS1v15DecryptOptions{...} — note the address-of operator.","Pass nil to default to PKCS#1 v1.5 decryption.","If you hold a generic crypto.DecrypterOpts, type-switch before calling Decrypt and translate unknown types rather than forwarding them."],"exampleFix":"// before: passed by value\npt, err := priv.Decrypt(rand.Reader, ct, rsa.OAEPOptions{Hash: crypto.SHA256})\n\n// after: passed by pointer\npt, err := priv.Decrypt(rand.Reader, ct, &rsa.OAEPOptions{Hash: crypto.SHA256})","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func isKnownRSAOpts(opts crypto.DecrypterOpts) bool {\n    if opts == nil { return true }\n    switch opts.(type) {\n    case *rsa.OAEPOptions, *rsa.PKCS1v15DecryptOptions:\n        return true\n    }\n    return false\n}","tryCatchPattern":null,"preventionTips":["Always pass &rsa.OAEPOptions{} or &rsa.PKCS1v15DecryptOptions{} — note the &.","Type-switch on crypto.DecrypterOpts in generic code before forwarding.","Pass nil when PKCS#1 v1.5 default is acceptable."],"tags":["rsa","oaep","type-error","api-misuse","crypto"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}