gofr-dev/gofr · error

modulus is empty

Error message

modulus is empty

What it means

errEmptyModulus is returned by rsaPublicKey in GoFr's OAuth middleware when a JSON Web Key (JWK) has an empty or missing 'n' (modulus) field. RSA public keys reconstructed from a JWKS endpoint require both the modulus and the exponent; without the modulus the key cannot be built for JWT signature verification.

Source

Thrown at pkg/gofr/http/middleware/oauth.go:24

	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"math/big"
	"net/http"
	"regexp"
	"strings"
	"sync"
	"time"

	"github.com/golang-jwt/jwt/v5"
)

var (
	errEmptyProvider       = errors.New("require non-empty provider")
	errInvalidInterval     = errors.New("invalid interval, require a value greater than 1 second")
	errEmptyModulus        = errors.New("modulus is empty")
	errEmptyPublicExponent = errors.New("public exponent is empty")
	errEmptyResponseBody   = errors.New("response body is empty")
	errInvalidURL          = errors.New("invalid URL")
)

const jwtRegexPattern = "^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+$"

// PublicKeys stores a map of public keys identified by their key ID (kid).
type PublicKeys struct {
	mu   sync.RWMutex
	keys map[string]*rsa.PublicKey
}

// JWKNotFound is an error type indicating a missing JSON Web Key Set (JWKS).
type JWKNotFound struct {
}

func (JWKNotFound) Error() string {

View on GitHub (pinned to 187eb24962)

Solutions

  1. Verify the JWKS endpoint returns valid RSA keys including both n and kty:"RSA" fields
  2. Check you're fetching the correct JWKS URL for your issuer
  3. Validate the JWK fields (modulus/exponent present, non-empty) before constructing the public key
  4. Handle the error by failing the token verification with 401 and logging the raw JWKS response for diagnosis

Example fix

// before
key, err := middleware.RSAPublicKey(jwk) // jwk.N == "" -> errEmptyModulus
// after
if jwk.N == "" || jwk.E == "" {
    return nil, fmt.Errorf("invalid JWK for kid %q: missing modulus/exponent", jwk.Kid)
}
key, err := middleware.RSAPublicKey(jwk)
Defensive patterns

Strategy: type-guard

Validate before calling

func validRSAJwk(k Jwk) bool {
    return k.Kty == "RSA" && k.N != "" && k.E != ""
}

Type guard

func hasModulus(k Jwk) bool { return k.N != "" }

Try / catch

key, err := rsaPublicKey(jwk)
if err != nil {
    if errors.Is(err, middleware.ErrEmptyModulus) {
        log.Errorf("JWK kid=%q has no modulus; JWKS endpoint or key type wrong", jwk.Kid)
        return nil, errors.New("token verification unavailable")
    }
    return nil, err
}

Prevention

When it happens

Trigger: Parsing a JWKS response where a key entry lacks the n field, the JWKS endpoint returns malformed/partial keys, or the base64url decoding yields an empty modulus value.

Common situations: Identity provider misconfiguration or a JWKS URL pointing at the wrong endpoint, proxy stripping the response body, or a key type mismatch (e.g. EC keys) whose fields don't map to RSA modulus/exponent.

Related errors


AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01). Data as JSON: /api/errors/2abe258a108827b4. Report an issue: GitHub.