Skip to content
ecdsa.com
golang-jwt/jwt (Go)Go

Error message

token signature is invalid: key is of invalid type: ECDSA verify expects *ecdsa.PublicKey

Also printed as

  • token signature is invalid: key is of invalid type: HMAC verify expects []byte
  • token signature is invalid: key is of invalid type: RSA verify expects *rsa.PublicKey
  • key is of invalid type: ECDSA sign expects *ecdsa.PrivateKey
  • key is of invalid type

v5 names the expected type ("ECDSA verify expects *ecdsa.PublicKey", "HMAC verify expects []byte"); v4 prints only "key is of invalid type". Because v5 reports it under `ErrTokenSignatureInvalid`, it looks like a signature failure at first glance.

golang-jwt/jwt (Go) — jwt.ErrInvalidKeyType

What it means

The value your `Keyfunc` returned (or the key passed to `SignedString`) has the wrong Go type for the token's algorithm. golang-jwt type-asserts the key: ES* verification needs `*ecdsa.PublicKey`, RS*/PS* need `*rsa.PublicKey`, EdDSA needs `ed25519.PublicKey`, HS* needs `[]byte`; signing needs the matching private key. No cryptography ran — the key never had a chance to be wrong, it was the wrong kind of object.

Why it happens

How to fix it

  1. 1.

    Parse PEM into a typed key once

    golang-jwt ships helpers for each key type. Parse at startup and return the typed key from the Keyfunc.

    go
    pub, err := jwt.ParseECPublicKeyFromPEM(pemBytes)      // ES256/384/512
    // rsaPub, err := jwt.ParseRSAPublicKeyFromPEM(pemBytes) // RS*/PS*
    // edPub, err := jwt.ParseEdPublicKeyFromPEM(pemBytes)   // EdDSA
    if err != nil {
    	log.Fatal(err)
    }
    token, err := jwt.Parse(raw, func(t *jwt.Token) (any, error) { return pub, nil },
    	jwt.WithValidMethods([]string{"ES256"}))
  2. 2.

    Return HMAC secrets as []byte

    Convert the secret to bytes and pin `WithValidMethods` to the HMAC algorithm so tokens with an asymmetric `alg` cannot reach that code path.

    go
    secret := []byte(os.Getenv("JWT_HMAC_SECRET")) // []byte, not string
    token, err := jwt.Parse(raw, func(t *jwt.Token) (any, error) { return secret, nil },
    	jwt.WithValidMethods([]string{"HS256"}))

Related errors

Browse the full signature error database