thephpleague/oauth2-server · error · OAuthServerException

Missing "Bearer" token

Error message

Missing "Bearer" token

What it means

Generic guard inside validateAuthorization(): after stripping the optional case-insensitive "Bearer " prefix from the Authorization header, the remaining JWT credential is empty. This fires when a client sends a syntactically present but credential-less header, e.g. "Authorization: Bearer" or "Bearer " — the header exists yet carries no actual access token to parse.

Solutions

  1. Ensure the header is 'Authorization: Bearer <non-empty JWT>'.
  2. Check the token variable isn't empty/null at the call site.
  3. Verify only one Authorization header is set (later headers can confuse getHeader()[0]).

Example fix

// before
$request = $request->withHeader('Authorization', 'Bearer ' . $maybeNullToken);
// after
if ($maybeNullToken !== null && $maybeNullToken !== '') {
    $request = $request->withHeader('Authorization', 'Bearer ' . $maybeNullToken);
}
Defensive patterns

Strategy: validation

Validate before calling

$header = $request->getHeaderLine('Authorization');
if (!preg_match('/^Bearer\s+\S+/i', $header)) {
    throw new \RuntimeException('Authorization header must be "Bearer <token>"');
}

Try / catch

try { $request = $validator->validateAuthorization($request); } catch (OAuthServerException $e) { return $e->generateHttpResponse(new Response(), 401); }

Prevention

When it happens

Trigger: Header like 'Authorization: Bearer ' (empty token) or 'Authorization: Basic abc123' where the regex strips nothing but the leftover is empty, or header is only whitespace.

Common situations: Client sends empty token variable in template interpolation ('Bearer {$token}'); wrong scheme (Basic vs Bearer); header set to 'Bearer' with no space/value.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of thephpleague/oauth2-server@9d2f6fc0a0 (2026-09-15). Data as JSON: /api/errors/47cde016e0ce80b6. Report an issue: GitHub.

Appendix: source

Thrown at src/AuthorizationValidators/BearerTokenValidator.php:106

                InMemory::plainText($publicKeyContents, $this->publicKey->getPassPhrase() ?? '')
            )
        );
    }

    /**
     * {@inheritdoc}
     */
    public function validateAuthorization(ServerRequestInterface $request): ServerRequestInterface
    {
        if ($request->hasHeader('authorization') === false) {
            throw OAuthServerException::accessDenied('Missing "Authorization" header');
        }

        $header = $request->getHeader('authorization');
        $jwt = trim((string) preg_replace('/^\s*Bearer\s/i', '', $header[0]));

        if ($jwt === '') {
            throw OAuthServerException::accessDenied('Missing "Bearer" token');
        }

        try {
            // Attempt to parse the JWT
            $token = $this->jwtConfiguration->parser()->parse($jwt);
        } catch (Exception $exception) {
            throw OAuthServerException::accessDenied($exception->getMessage(), null, $exception);
        }

        try {
            // Attempt to validate the JWT
            $constraints = $this->jwtConfiguration->validationConstraints();
            $this->jwtConfiguration->validator()->assert($token, ...$constraints);
        } catch (RequiredConstraintsViolated $exception) {
            throw OAuthServerException::accessDenied('Access token could not be verified', null, $exception);
        }

        if (!$token instanceof UnencryptedToken) {

View on GitHub (pinned to 9d2f6fc0a0)