{"record":{"id":"b34c3abcbfaf83e0","repo":"lcobucci/jwt","slug":"the-jwt-string-is-missing-the-header-part","errorCode":null,"errorMessage":"The JWT string is missing the Header part","messagePattern":"The JWT string is missing the Header part","errorType":"exception","errorClass":"Lcobucci\\JWT\\Token\\InvalidTokenStructure","httpStatus":null,"severity":"error","filePath":"src/Token/Parser.php","lineNumber":31,"sourceCode":"use function explode;\nuse function is_array;\nuse function is_numeric;\nuse function number_format;\n\nfinal readonly class Parser implements ParserInterface\n{\n    private const int MICROSECOND_PRECISION = 6;\n\n    public function __construct(private Decoder $decoder)\n    {\n    }\n\n    public function parse(string $jwt): TokenInterface\n    {\n        [$encodedHeaders, $encodedClaims, $encodedSignature] = $this->splitJwt($jwt);\n\n        if ($encodedHeaders === '') {\n            throw InvalidTokenStructure::missingHeaderPart();\n        }\n\n        if ($encodedClaims === '') {\n            throw InvalidTokenStructure::missingClaimsPart();\n        }\n\n        if ($encodedSignature === '') {\n            throw InvalidTokenStructure::missingSignaturePart();\n        }\n\n        $header = $this->parseHeader($encodedHeaders);\n\n        return new Plain(\n            new DataSet($header, $encodedHeaders),\n            new DataSet($this->parseClaims($encodedClaims), $encodedClaims),\n            $this->parseSignature($encodedSignature),\n        );\n    }","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/lcobucci/jwt/blob/375813049c24c7111bda8b6884c57b071ceb2fe7/src/Token/Parser.php#L13-L49","documentation":"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.","triggerScenarios":"Calling (new Parser())->parse('') or parse('.payload.sig') — an empty string or a token whose first segment before the first dot is empty.","commonSituations":"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.","solutions":["Check the token is non-empty before parsing: if ($jwt === '') skip/throw early","Strip the 'Bearer ' prefix correctly and verify a value remains: substr($header, 7)","Log/inspect where the token comes from (env var, request header, cookie) — it is likely missing entirely","Use JwtFacade or a presence check before invoking Parser"],"exampleFix":"// before\n$token = $parser->parse($_SERVER['HTTP_AUTHORIZATION']);\n// after\n$bearer = $_SERVER['HTTP_AUTHORIZATION'] ?? '';\n$jwt = str_starts_with($bearer, 'Bearer ') ? substr($bearer, 7) : $bearer;\nif ($jwt === '') {\n    throw new InvalidArgumentException('No JWT provided');\n}\n$token = $parser->parse($jwt);","handlingStrategy":"validation","validationCode":"if ($jwt === '' || str_starts_with($jwt, '.')) { throw new InvalidArgumentException('JWT header missing'); }","typeGuard":null,"tryCatchPattern":"try { $token = $parser->parse($jwt); } catch (Lcobucci\\JWT\\InvalidTokenStructure $e) { return error_401('Malformed token'); }","preventionTips":["Check token presence before parsing (empty Authorization header is the top cause)","Strip 'Bearer ' prefix and re-check for emptiness","Centralize token extraction in one guarded helper"],"tags":["jwt","parser","malformed-token","php"],"backgroundTag":"invalid-argument-format","analyzedSha":"375813049c24c7111bda8b6884c57b071ceb2fe7","analyzedAt":"2026-09-14T11:12:28.004Z","contentChangedAt":"2026-09-14T11:12:28.004Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}