golang/go · error · ErrDecryption

crypto/rsa: decryption error

Error message

crypto/rsa: decryption error

What it means

ErrDecryption is a sentinel error (var) returned by OAEP and PKCS#1 v1.5 decryption when the ciphertext cannot be unwrapped — wrong key, corrupted ciphertext, invalid padding, or a session-key-length mismatch. The comment is explicit: 'It is deliberately vague to avoid adaptive attacks.' Callers must NOT branch on the specific cause; treat every ErrDecryption identically to avoid leaking padding-validity via timing.

Source

Thrown at src/crypto/rsa/rsa.go:545

		}
	}

	priv.Precompute()
	if err := priv.Validate(); err != nil {
		return nil, err
	}

	return priv, nil
}

// ErrMessageTooLong is returned when attempting to encrypt or sign a message
// which is too large for the size of the key. When using [SignPSS], this can also
// be returned if the size of the salt is too large.
var ErrMessageTooLong = errors.New("crypto/rsa: message too long for RSA key size")

// ErrDecryption represents a failure to decrypt a message.
// It is deliberately vague to avoid adaptive attacks.
var ErrDecryption = errors.New("crypto/rsa: decryption error")

// ErrVerification represents a failure to verify a signature.
// It is deliberately vague to avoid adaptive attacks.
var ErrVerification = errors.New("crypto/rsa: verification error")

// Precompute performs some calculations that speed up private key operations in
// the future. It is safe to run on non-validated private keys, and it can speed
// up future calls to [PrivateKey.Validate] for valid keys.
//
// Precompute writes to the Precomputed field, so it must not be called
// concurrently with any other method.
//
// Precompute does not return an error. Applications should call
// [PrivateKey.Validate] after Precompute to check for any problems with the
// key, including any that would cause Precompute to fail.
//
// Calling Precompute on a key that has already been precomputed is a no-op.
func (priv *PrivateKey) Precompute() {

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Verify the key identity (kid) before decrypting; map ciphertext to the right private key.
  2. Handle ErrDecryption uniformly: errors.Is(err, rsa.ErrDecryption) — do not log specifics or distinguish causes in user-visible behavior.
  3. Re-encrypt/rotate the data with the current key if a key rotation mismatch is found.
  4. For session-key decryption (DecryptPKCS1v15SessionKey), note that the output buffer is randomized on failure to keep timing constant — do not assume the plaintext is valid just because no error propagated in some wrappers.

Example fix

// before
pt, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, priv, ct, nil)
if err != nil {
    log.Printf("decryption failed: %v", err) // leaks specifics
}

// after
pt, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, priv, ct, nil)
if err != nil {
    // do not log or branch on the cause
    return errors.New("invalid ciphertext")
}
Defensive patterns

Strategy: try-catch

Try / catch

pt, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, priv, ct, nil)
if errors.Is(err, rsa.ErrDecryption) {
    // uniform handling: no logging of the cause, no differentiated response
    return errors.New("invalid ciphertext")
}

Prevention

When it happens

Trigger: rsa.DecryptOAEP with the wrong private key; DecryptPKCS1v15 on truncated ciphertext; DecryptPKCS1v15SessionKey where the padding bytes do not decode; ciphertext tampered in transit (authenticity failure).

Common situations: Wrong key selected from a keyring (kid mismatch); storage bit-rot; cross-system handoff where the peer encrypted with one pub key but you decrypt with another; replaying old ciphertext against a rotated key.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/0e40d70073fd0048. Report an issue: GitHub.