Skip to content
ecdsa.com
firebase/php-jwt (PHP)PHP

Error message

Wrong number of segments

Also printed as

  • UnexpectedValueException: Wrong number of segments
  • Unexpected control character found

Prefixed with the class name when printed: "UnexpectedValueException: Wrong number of segments". The `Bearer` prefix case produces "Unexpected control character found" (a `DomainException`) instead.

firebase/php-jwt (PHP) — UnexpectedValueException from JWT::decode

What it means

`JWT::decode` split the input on dots and did not get exactly three parts, so it is not a compact JWS and nothing else was checked. In PHP applications the most common source is an empty string: the web server did not pass the `Authorization` header to PHP, and the code fell back to `''`. A token that still carries the `Bearer ` prefix has three segments but fails one step later, typically with "Unexpected control character found" from the JSON decoder.

Why it happens

How to fix it

  1. 1.

    Read the header robustly and validate the shape

    Look in the places different server setups put the header, accept only `Bearer <three base64url segments>`, and answer 401 otherwise.

    php
    function bearerToken(): ?string
    {
        $header = $_SERVER['HTTP_AUTHORIZATION']
            ?? $_SERVER['REDIRECT_HTTP_AUTHORIZATION']      // Apache + mod_rewrite
            ?? (function_exists('apache_request_headers') ? (apache_request_headers()['Authorization'] ?? '') : '');
        if (!preg_match('/^Bearer\s+([A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]*)$/', $header, $m)) {
            return null;
        }
        return $m[1];
    }
  2. 2.

    Make Apache pass the header

    `CGIPassAuth On` (Apache 2.4.13+) or a rewrite rule exposes `Authorization` to PHP.

    text
    # Apache with PHP-FPM / CGI: pass the Authorization header through
    CGIPassAuth On
    # or, with mod_rewrite:
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Related errors

Browse the full signature error database