golang/go · error · ErrMessageTooLong

crypto/rsa: message too long for RSA key size

Error message

crypto/rsa: message too long for RSA key size

What it means

ErrMessageTooLong is a sentinel error (var, not a stringly-typed error) returned when an encrypt or sign input is too large for the key size and selected padding. Concretely: PKCS#1 v1.5 encrypt needs len(msg) <= k-11; OAEP needs len(msg) <= k - 2*hashLen - 2; PSS signing needs len(msg)+saltLen <= k-2 (oversized salt included). Callers should compare with errors.Is because the same var is reused across EncryptPKCS1v15/EncryptOAEP/SignPSS.

Source

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

		if ok != nil {
			priv.Primes = primes
			priv.N = n
			break
		}
	}

	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

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Use hybrid encryption: encrypt a random AES key with RSA, then AES-GCM the payload.
  2. Switch to a larger RSA key (3072/4096) to gain payload budget.
  3. For PSS, set opts.SaltLength explicitly (e.g. rsa.PSSSaltLength auto-fits) instead of a fixed large value.
  4. Compare with errors.Is(err, rsa.ErrMessageTooLong) to differentiate from other RSA errors.

Example fix

// before: encrypting a large payload directly
ct, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, pub, bigMsg, nil) // err: message too long

// after: hybrid encryption
key := make([]byte, 32)
rand.Read(key)
wrapped, _ := rsa.EncryptOAEP(sha256.New(), rand.Reader, pub, key, nil)
ct := aesgcmSeal(key, bigMsg) // AES-GCM payload separately
Defensive patterns

Strategy: validation

Validate before calling

func maxOAEPBytes(pub *rsa.PublicKey, h crypto.Hash) int {
    return pub.Size() - 2*h.Size() - 2
}
if len(msg) > maxOAEPBytes(pub, crypto.SHA256) {
    return errors.New("payload too large for RSA-OAEP; use hybrid encryption")
}

Try / catch

if errors.Is(err, rsa.ErrMessageTooLong) {
    // switch to hybrid: wrap a random AES key with RSA-OAEP, AES-GCM the payload
}

Prevention

When it happens

Trigger: rsa.EncryptPKCS1v15(rand.Reader, pub, bigMsg) with len(bigMsg) > pub.Size()-11; rsa.EncryptOAEP with a payload larger than k-2*hLen-2; rsa.SignPSS with a salt length that, combined with the message digest input, exceeds the modulus; using a 1024-bit key to encrypt a 256-byte message.

Common situations: Forgetting that RSA encrypts only small payloads (symmetric keys, digests) and trying to encrypt arbitrary data directly; switching from PKCS#1 v1.5 to OAEP without re-checking the size budget (OAEP has tighter overhead); PSS with SaltLength = rsa.PSSSaltLengthEqualsHash on a key whose modulus is too small.

Related errors


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