golang/go · error
crypto/rsa: use of public exponent <= 2¹⁶ is not allowed in
Error message
crypto/rsa: use of public exponent <= 2¹⁶ is not allowed in FIPS 140-only mode
What it means
Thrown by checkFIPS140OnlyPublicKey when fips140only.Enforced() and pub.E <= 1<<16 (65536). FIPS requires the public exponent to be strictly greater than 2^16 and odd. The standard exponent 65537 (0x10001) passes since 65537 > 65536; small exponents like 3, 17, 257, and 65537-1=65536 all fail. This rejects weak/small exponents mandated out by FIPS 186-4 section 5.1 and B.3.1.
Source
Thrown at src/crypto/rsa/fips.go:450
func fipsError2[T any](x T, err error) (T, error) {
return x, fipsError(err)
}
func checkFIPS140OnlyPublicKey(pub *PublicKey) error {
if !fips140only.Enforced() {
return nil
}
if pub.N == nil {
return errors.New("crypto/rsa: public key missing N")
}
if pub.N.BitLen() < 2048 {
return errors.New("crypto/rsa: use of keys smaller than 2048 bits is not allowed in FIPS 140-only mode")
}
if pub.N.BitLen()%2 == 1 {
return errors.New("crypto/rsa: use of keys with odd size is not allowed in FIPS 140-only mode")
}
if pub.E <= 1<<16 {
return errors.New("crypto/rsa: use of public exponent <= 2¹⁶ is not allowed in FIPS 140-only mode")
}
if pub.E&1 == 0 {
return errors.New("crypto/rsa: use of even public exponent is not allowed in FIPS 140-only mode")
}
return nil
}
func checkFIPS140OnlyPrivateKey(priv *PrivateKey) error {
if !fips140only.Enforced() {
return nil
}
if err := checkFIPS140OnlyPublicKey(&priv.PublicKey); err != nil {
return err
}
if len(priv.Primes) != 2 {
return errors.New("crypto/rsa: use of multi-prime keys is not allowed in FIPS 140-only mode")
}
if priv.Primes[0] == nil || priv.Primes[1] == nil || priv.Primes[0].BitLen() != priv.Primes[1].BitLen() {View on GitHub (pinned to b6b368adc5)
Solutions
- Regenerate the key with the default exponent 65537: rsa.GenerateKey uses 65537 automatically.
- Validate at load time: if pub.E <= 1<<16 { reject }.
- Rotate all peers/certs off small-exponent keys.
Example fix
// before // key with E = 3 sig, err := rsa.SignPSS(rand.Reader, weakExpKey, crypto.SHA256, digest, opts) // after priv, _ := rsa.GenerateKey(rand.Reader, 2048) // E defaults to 65537 sig, err := rsa.SignPSS(rand.Reader, priv, crypto.SHA256, digest, opts)
Defensive patterns
Strategy: validation
Validate before calling
if pub.E <= 1<<16 {
return fmt.Errorf("public exponent E=%d must be > 2^16 (65536) in FIPS-only mode; use 65537", pub.E)
}
// proceed Type guard
func exponentIsFIPSCompliant(e int) bool {
return e > 1<<16 && e&1 == 1
} Prevention
- Always use 65537 as the public exponent — rsa.GenerateKey defaults to it.
- Reject keys with small exponents (3, 17, 257) at load time.
- Never construct rsa.PublicKey literals with a hand-picked E.
When it happens
Trigger: Using a key generated with exponent 3 or 17 (historically used for performance). A key with E == 65536 (even AND <= 2^16, also trips 498). Constructing a key literal with pub.E set too low.
Common situations: Legacy keys generated decades ago with E=3 for speed. Custom key-generation code that set E to a small prime. Keys from constrained environments that minimized exponent size.
Related errors
- crypto/rsa: use of even public exponent is not allowed in FI
- crypto/rsa: public key missing N
- crypto/rsa: use of keys with odd size is not allowed in FIPS
- crypto/rsa: use of multi-prime keys is not allowed in FIPS 1
- crypto/rsa: use of primes of different sizes is not allowed
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/8ce3a40ebbba8edd.
Report an issue: GitHub.