golang/go · error
crypto/rsa: invalid options for Decrypt
Error message
crypto/rsa: invalid options for Decrypt
What it means
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.
Source
Thrown at src/crypto/rsa/rsa.go:206
return decryptOAEP(opts.Hash.New(), opts.MGFHash.New(), priv, ciphertext, opts.Label)
}
case *PKCS1v15DecryptOptions:
if l := opts.SessionKeyLen; l > 0 {
plaintext = make([]byte, l)
if _, err := io.ReadFull(rand, plaintext); err != nil {
return nil, err
}
if err := DecryptPKCS1v15SessionKey(rand, priv, ciphertext, plaintext); err != nil {
return nil, err
}
return plaintext, nil
} else {
return DecryptPKCS1v15(rand, priv, ciphertext)
}
default:
return nil, errors.New("crypto/rsa: invalid options for Decrypt")
}
}
type PrecomputedValues struct {
Dp, Dq *big.Int // D mod (P-1) (or mod Q-1)
Qinv *big.Int // Q^-1 mod P
// CRTValues is used for the 3rd and subsequent primes. Due to a
// historical accident, the CRT for the first two primes is handled
// differently in PKCS #1 and interoperability is sufficiently
// important that we mirror this.
//
// Deprecated: These values are still filled in by Precompute for
// backwards compatibility but are not used. Multi-prime RSA is very rare,
// and is implemented by this package without CRT optimizations to limit
// complexity.
CRTValues []CRTValue
View on GitHub (pinned to b6b368adc5)
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.
Example fix
// before: passed by value
pt, err := priv.Decrypt(rand.Reader, ct, rsa.OAEPOptions{Hash: crypto.SHA256})
// after: passed by pointer
pt, err := priv.Decrypt(rand.Reader, ct, &rsa.OAEPOptions{Hash: crypto.SHA256}) Defensive patterns
Strategy: type-guard
Type guard
func isKnownRSAOpts(opts crypto.DecrypterOpts) bool {
if opts == nil { return true }
switch opts.(type) {
case *rsa.OAEPOptions, *rsa.PKCS1v15DecryptOptions:
return true
}
return false
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Generic crypto code that accepts crypto.DecrypterOpts from a caller and forwards it without narrowing; copy-paste mistake omitting the & on OAEPOptions.
Related errors
- crypto/rsa: unsupported hash function
- rsa: requested hash function unavailable: {hash}
- rsa: requested hash function unavailable: {mgfHash}
- crypto/rsa: missing primes
- crypto/rsa: GenerateMultiPrimeKey: nprimes must be >= 2
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/8752d2040a43960c.
Report an issue: GitHub.