golang/go · error

crypto/rsa: missing public modulus

Error message

crypto/rsa: missing public modulus

What it means

Thrown by checkPublicKey when pub.N is nil — the public modulus is entirely missing. N is the RSA modulus (product of the two primes) and every RSA operation needs it; a nil N means the PublicKey was not initialized, so the key is unusable.

Source

Thrown at src/crypto/internal/fips140/rsa/rsa.go:329

	}

	// Check that d > 2^(nlen/2).
	//
	// See section 3 of https://crypto.stanford.edu/~dabo/papers/RSA-survey.pdf
	// for more details about attacks on small d values.
	//
	// Likewise, the leakage of the magnitude of d is not adaptive.
	if priv.d.BitLenVarTime() <= N.BitLen()/2 {
		return errors.New("crypto/rsa: d too small")
	}

	return nil
}

func checkPublicKey(pub *PublicKey) (fipsApproved bool, err error) {
	fipsApproved = true
	if pub.N == nil {
		return false, errors.New("crypto/rsa: missing public modulus")
	}
	if pub.N.Nat().IsOdd() == 0 {
		return false, errors.New("crypto/rsa: public modulus is even")
	}
	// FIPS 186-5, Section 5.1: "This standard specifies the use of a modulus
	// whose bit length is an even integer and greater than or equal to 2048
	// bits."
	if pub.N.BitLen() < 2048 {
		fipsApproved = false
	}
	if pub.N.BitLen()%2 == 1 {
		fipsApproved = false
	}
	if pub.E < 2 {
		return false, errors.New("crypto/rsa: public exponent too small or negative")
	}
	// e needs to be coprime with p-1 and q-1, since it must be invertible
	// modulo λ(pq). Since p and q are prime, this means e needs to be odd.

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Ensure the PublicKey is constructed from parsed material (e.g. via x509.ParsePKIXPublicKey) and N is set.
  2. Guard usage with a nil check on pub.N before any RSA operation.
  3. Regenerate the key pair and use the public key from rsa.GenerateKey directly.

Example fix

// before
var pub rsa.PublicKey // zero value, N is nil
enc, err := rsa.EncryptOAEP(h, rand, &pub, msg, nil)

// after
pub, ok := parsed.(*rsa.PublicKey)
if !ok || pub.N == nil {
    return errors.New("missing RSA public modulus")
}
enc, err := rsa.EncryptOAEP(h, rand, pub, msg, nil)
Defensive patterns

Strategy: type-guard

Validate before calling

if pub == nil || pub.N == nil {
    return errors.New("RSA public key missing modulus")
}

Type guard

func hasModulus(pub *rsa.PublicKey) bool { return pub != nil && pub.N != nil }

Try / catch

if err := op(pub); err != nil {
    if strings.Contains(err.Error(), "missing public modulus") {
        // re-parse or regenerate the public key
    }
    return err
}

Prevention

When it happens

Trigger: checkPublicKey runs (during encryption, decryption, signing, verification, or key validation) and pub.N == nil. Reached on any RSA operation that validates the public key.

Common situations: A zero-value rsa.PublicKey used before population. A parse error that returned a partial key without setting N. A nil pointer or missing field in imported key JSON/ASN.1.

Related errors


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