Mensaje de error
Invalid compact JWT string: Compact JWSs must contain exactly 2 period characters, and compact JWEs must contain exactly 4. Found: 0
También se muestra como
- io.jsonwebtoken.MalformedJwtException: Invalid compact JWT string: Compact JWSs must contain exactly 2 period characters, and compact JWEs must contain exactly 4. Found: 1
- io.jsonwebtoken.MalformedJwtException: Compact JWT strings may not contain whitespace.
- io.jsonwebtoken.MalformedJwtException: JWT strings must contain exactly 2 period characters. Found: 0
Texto de JJWT 0.12+ (fíjate en los dos espacios antes de «Found»). JJWT 0.11 y las versiones anteriores decían «JWT strings must contain exactly 2 period characters. Found: N». Una entrada con espacios falla antes, con «Compact JWT strings may not contain whitespace.»
JJWT (Java) — io.jsonwebtoken.MalformedJwtException from JwtParser.parse*
Qué significa
JJWT contó los puntos de la entrada y no encontró ni los 2 de un token firmado (JWS) ni los 4 de uno cifrado (JWE). La cadena no es un JWT compacto, así que no se examinó ninguna clave ni firma. «Found: 0» suele indicar un valor opaco, como un ID de sesión o una clave de API; una queja por espacios en blanco indica que sigue pegado el prefijo `Bearer` o un salto de línea.
Por qué ocurre
El valor no es un JWT
frecuenteTokens OAuth opacos, cookies de sesión, claves de API, `"null"` o un valor de encabezado vacío. Solo las cadenas de segmentos base64url separados por puntos son JWT compactos.
Se pasó el encabezado Authorization entero
frecuente`Bearer eyJ…` contiene un espacio, que JJWT rechaza antes de contar los puntos. Quita primero el esquema.
Falta parte del token
ocasionalUn token cortado en un punto (registros truncados, columnas de tamaño limitado, copia manual) deja un solo punto («Found: 1»).
Cómo solucionarlo
- 1.
Extraer el token del encabezado correctamente
Acepta solo `Bearer <token>` (con el esquema sin distinguir mayúsculas de minúsculas) y responde 401 a todo lo demás.
java static String bearerToken(String authorizationHeader) { if (authorizationHeader == null) return null; String[] parts = authorizationHeader.trim().split("\\s+", 2); if (parts.length != 2 || !parts[0].equalsIgnoreCase("Bearer")) return null; return parts[1]; } - 2.
O dejar que lo extraiga el framework
La función de servidor de recursos de Spring Security extrae y valida los tokens de portador, incluidas las respuestas de error del RFC 6750.
java // Spring Security resource server: the BearerTokenAuthenticationFilter extracts the token for you. @Bean SecurityFilterChain api(HttpSecurity http) throws Exception { return http .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) .oauth2ResourceServer(oauth -> oauth.jwt(Customizer.withDefaults())) .build(); }