lcobucci/jwt · error · Lcobucci\JWT\Token\InvalidTokenStructure

The JWT string is missing the Header part

Error message

The JWT string is missing the Header part

What it means

Parser::parse() splits the JWT on '.' and requires three non-empty segments (header, claims, signature). If the first (header) segment is empty, InvalidTokenStructure::missingHeaderPart() is thrown. A JWT must always start with a non-empty Base64Url-encoded header.

Solutions

  1. Check the token is non-empty before parsing: if ($jwt === '') skip/throw early
  2. Strip the 'Bearer ' prefix correctly and verify a value remains: substr($header, 7)
  3. Log/inspect where the token comes from (env var, request header, cookie) — it is likely missing entirely
  4. Use JwtFacade or a presence check before invoking Parser

Example fix

// before
$token = $parser->parse($_SERVER['HTTP_AUTHORIZATION']);
// after
$bearer = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
$jwt = str_starts_with($bearer, 'Bearer ') ? substr($bearer, 7) : $bearer;
if ($jwt === '') {
    throw new InvalidArgumentException('No JWT provided');
}
$token = $parser->parse($jwt);
Defensive patterns

Strategy: validation

Validate before calling

if ($jwt === '' || str_starts_with($jwt, '.')) { throw new InvalidArgumentException('JWT header missing'); }

Try / catch

try { $token = $parser->parse($jwt); } catch (Lcobucci\JWT\InvalidTokenStructure $e) { return error_401('Malformed token'); }

Prevention

When it happens

Trigger: Calling (new Parser())->parse('') or parse('.payload.sig') — an empty string or a token whose first segment before the first dot is empty.

Common situations: Reading the token from an empty Authorization header (only 'Bearer ' prefix, no token); config/env var not set so the token variable is ''; a token where the signature dot-count is right but the header was stripped.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of lcobucci/jwt@375813049c (2026-09-14). Data as JSON: /api/errors/b34c3abcbfaf83e0. Report an issue: GitHub.

Appendix: source

Thrown at src/Token/Parser.php:31

use function explode;
use function is_array;
use function is_numeric;
use function number_format;

final readonly class Parser implements ParserInterface
{
    private const int MICROSECOND_PRECISION = 6;

    public function __construct(private Decoder $decoder)
    {
    }

    public function parse(string $jwt): TokenInterface
    {
        [$encodedHeaders, $encodedClaims, $encodedSignature] = $this->splitJwt($jwt);

        if ($encodedHeaders === '') {
            throw InvalidTokenStructure::missingHeaderPart();
        }

        if ($encodedClaims === '') {
            throw InvalidTokenStructure::missingClaimsPart();
        }

        if ($encodedSignature === '') {
            throw InvalidTokenStructure::missingSignaturePart();
        }

        $header = $this->parseHeader($encodedHeaders);

        return new Plain(
            new DataSet($header, $encodedHeaders),
            new DataSet($this->parseClaims($encodedClaims), $encodedClaims),
            $this->parseSignature($encodedSignature),
        );
    }

View on GitHub (pinned to 375813049c)