Mensaje de error
token is malformed: token contains an invalid number of segments
También se muestra como
- token is malformed: could not base64 decode header: illegal base64 data at input byte 6
- token contains an invalid number of segments
La v5 antepone «token is malformed: ». La v4 solo imprime el texto interno, por ejemplo «token contains an invalid number of segments». El desplazamiento de byte en «illegal base64 data at input byte N» apunta al primer carácter incorrecto.
golang-jwt/jwt (Go) — jwt.ErrTokenMalformed
Qué significa
golang-jwt ni siquiera puede leer la estructura del token. «invalid number of segments» significa que la cadena no tiene exactamente dos puntos; «could not base64 decode header» significa que el primer segmento no es base64url, en el caso clásico porque sigue pegado el prefijo `Bearer ` (el byte 6 es el espacio). En la v5, estos errores se envuelven en `jwt.ErrTokenMalformed`; no se llega a buscar ninguna clave.
Por qué ocurre
Se pasa al analizador el encabezado Authorization entero
frecuente`r.Header.Get("Authorization")` devuelve `Bearer eyJ…`. Si se pasa directamente a `jwt.Parse`, el espacio convierte el segmento del encabezado en base64 no válido.
El valor no es un JWT
frecuenteAl analizador llegan tokens de acceso OAuth opacos, ID de sesión, claves de API o un encabezado vacío. Solo las cadenas con tres segmentos base64url son tokens JWS.
Un token cifrado (JWE) con cinco segmentos
ocasionalAlgunos proveedores de identidad cifran los tokens. golang-jwt solo maneja tokens firmados; descifra primero el JWE (por ejemplo, con go-jose) y analiza el JWS anidado.
El token está truncado
ocasionalUna columna de base de datos, el límite de tamaño de una cookie (4 KB) o una línea de registro cortan el token y eliminan el último segmento o el último punto.
Cómo solucionarlo
- 1.
Usar el extractor de solicitudes
`github.com/golang-jwt/jwt/v5/request` quita el esquema `Bearer` sin distinguir mayúsculas de minúsculas y devuelve `request.ErrNoTokenInRequest` cuando no hay ningún token.
go import "github.com/golang-jwt/jwt/v5/request" token, err := request.ParseFromRequest(r, request.OAuth2Extractor, keyfunc, request.WithParser(jwt.NewParser(jwt.WithValidMethods([]string{"ES256"})))) if err != nil { http.Error(w, "unauthorized", http.StatusUnauthorized) return } - 2.
Validar la forma antes de analizar
Contar los puntos distingue JWS (2), JWE (4) y basura. Responde 401 a todo lo que no sea un token que puedas procesar.
go raw := strings.TrimSpace(strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ")) switch strings.Count(raw, ".") { case 2: // JWS: parse it case 4: // JWE: decrypt first (go-jose), golang-jwt does not handle encrypted tokens default: http.Error(w, "unauthorized", http.StatusUnauthorized) return }