{"record":{"id":"b6b042be03f6ec41","repo":"spring-projects/spring-security","slug":"invalid-token-b6b042","errorCode":"invalid_token","errorMessage":"Bearer token is malformed","messagePattern":"Bearer token is malformed","errorType":"error_code","errorClass":"OAuth2AuthenticationException","httpStatus":401,"severity":"error","filePath":"oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/server/authentication/ServerBearerTokenAuthenticationConverter.java","lineNumber":108,"sourceCode":"\t\tif (!StringUtils.hasText(accessToken)) {\n\t\t\tBearerTokenError error = BearerTokenErrors\n\t\t\t\t.invalidRequest(\"The requested token parameter is an empty string\");\n\t\t\treturn Mono.error(new OAuth2AuthenticationException(error));\n\t\t}\n\n\t\treturn Mono.just(accessToken);\n\t}\n\n\tprivate Mono<String> resolveFromAuthorizationHeader(HttpHeaders headers) {\n\t\tString authorization = headers.getFirst(this.bearerTokenHeaderName);\n\t\tif (!StringUtils.startsWithIgnoreCase(authorization, \"bearer\")) {\n\t\t\treturn Mono.empty();\n\t\t}\n\n\t\tMatcher matcher = authorizationPattern.matcher(authorization);\n\t\tif (!matcher.matches()) {\n\t\t\tBearerTokenError error = BearerTokenErrors.invalidToken(\"Bearer token is malformed\");\n\t\t\tthrow new OAuth2AuthenticationException(error);\n\t\t}\n\n\t\treturn Mono.just(matcher.group(\"token\"));\n\t}\n\n\tprivate Flux<String> resolveAccessTokenFromQueryString(ServerHttpRequest request) {\n\t\tif (!this.allowUriQueryParameter || !HttpMethod.GET.equals(request.getMethod())) {\n\t\t\treturn Flux.empty();\n\t\t}\n\n\t\treturn resolveTokens(request.getQueryParams());\n\t}\n\n\tprivate Flux<String> resolveAccessTokenFromBody(ServerWebExchange exchange) {\n\t\tServerHttpRequest request = exchange.getRequest();\n\t\tif (!this.allowFormEncodedBodyParameter\n\t\t\t\t|| !MediaType.APPLICATION_FORM_URLENCODED.equals(request.getHeaders().getContentType())\n\t\t\t\t|| !HttpMethod.POST.equals(request.getMethod())) {","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-resource-server/src/main/java/org/springframework/security/oauth2/server/resource/web/server/authentication/ServerBearerTokenAuthenticationConverter.java#L90-L126","documentation":"The reactive (WebFlux) ServerBearerTokenAuthenticationConverter throws this when the Authorization header starts with 'Bearer ' but the remainder fails the token regex — typically whitespace or multiple values. It is the reactive counterpart of error 460 and maps to the invalid_token OAuth2 error before any token validation.","triggerScenarios":"A WebFlux application receives 'Authorization: Bearer <value>' where <value> contains spaces, a newline, or multiple space-separated tokens, so authorizationPattern.matcher(authorization).matches() fails inside resolveFromAuthorizationHeader.","commonSituations":"Tokens copied with trailing whitespace from terminals or logs; clients URL-encoding or wrapping tokens; gateway header rewriting inserting spaces; empty bearer values ('Bearer ' with nothing after).","solutions":["Trim the token and rebuild the header so it is exactly 'Bearer <token>'","Regenerate the token if it contains characters outside the RFC token charset","Inspect the raw header at the edge (e.g. with a WebFilter) to find what is actually transmitted","Use a custom ServerBearerTokenAuthenticationConverter if your tokens legitimately deviate from the default pattern"],"exampleFix":"// before\nwebClient.defaultHeader(HttpHeaders.AUTHORIZATION, \"Bearer \" + token);\n// after\nwebClient.defaultHeader(HttpHeaders.AUTHORIZATION, \"Bearer \" + token.trim());","handlingStrategy":"validation","validationCode":"String auth = request.getHeaders().getFirst(HttpHeaders.AUTHORIZATION);\nif (auth != null && auth.startsWith(\"Bearer \")) {\n    String token = auth.substring(7).trim();\n    if (token.isEmpty() || token.contains(\" \")) {\n        return Mono.error(new IllegalArgumentException(\"Malformed bearer token\"));\n    }\n}","typeGuard":"boolean isValidBearerHeader(String header) {\n    return header != null && header.matches(\"^Bearer [!-~]+$\");\n}","tryCatchPattern":"try {\n    return chain.filter(exchange);\n} catch (OAuth2AuthenticationException e) {\n    if (\"invalid_token\".equals(e.getError().getErrorCode())) {\n        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);\n        exchange.getResponse().getHeaders().add(\"WWW-Authenticate\", \"Bearer error=\\\"invalid_token\\\"\");\n    }\n    return Mono.error(e);\n}","preventionTips":["Normalize tokens (trim) at client construction time, once","Add a WebFilter-level test that asserts a well-formed Authorization header","Avoid string concatenation for headers; use header-builder APIs","Watch for reactive clients adding headers per-request alongside defaults"],"tags":["oauth2","bearer-token","webflux","spring-security","reactive"],"backgroundTag":"invalid-token-format","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}