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

Builder#withClaim() is meant to be used for non-registered…

Error message

Builder#withClaim() is meant to be used for non-registered claims, check the documentation on how to set claim "%s"

What it means

Builder::withClaim() is reserved for private (non-registered) claims. If the claim name is one of the IANA-registered JWT claims (iss, sub, aud, exp, nbf, iat, jti, etc.), the builder refuses and throws RegisteredClaimGiven::forClaim(), because registered claims need typed values and dedicated methods.

Solutions

  1. Use the dedicated builder methods: issuedBy(), relatedTo(), permittedFor(), identifiedBy(), canOnlyBeUsedAfter(), expiresAt(), issuedAt()
  2. For time claims pass DateTimeImmutable objects to expiresAt()/issuedAt()/canOnlyBeUsedAfter() rather than raw values via withClaim
  3. Keep withClaim() only for custom/private claim names not in RegisteredClaims::ALL

Example fix

// before
$builder->withClaim('iss', 'https://my.issuer')->withClaim('exp', time() + 3600);
// after
$builder->issuedBy('https://my.issuer')
        ->issuedAt(new DateTimeImmutable())
        ->expiresAt(new DateTimeImmutable('+1 hour'));
Defensive patterns

Strategy: validation

Validate before calling

if (in_array($name, Lcobucci\JWT\Token\RegisteredClaims::ALL, true)) { useDedicatedBuilderMethod($name); }

Prevention

When it happens

Trigger: Calling $builder->withClaim('iss', ...), withClaim('exp', ...), withClaim('aud', ...) or any other name present in lcobucci\jwt\signing or Token\RegisteredClaims::ALL.

Common situations: Copy-pasted code building tokens that sets standard claims generically; migration from another JWT library where all claims were set through one method; setting 'exp' or 'iat' as raw ints instead of using the typed API (which handles DateTimeImmutable conversion).

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/Token/Builder.php:95

    }

    public function withHeader(string $name, mixed $value): BuilderInterface
    {
        $headers        = $this->headers;
        $headers[$name] = $value;

        return new self(
            $this->encoder,
            $this->claimFormatter,
            $headers,
            $this->claims,
        );
    }

    public function withClaim(string $name, mixed $value): BuilderInterface
    {
        if (in_array($name, RegisteredClaims::ALL, true)) {
            throw RegisteredClaimGiven::forClaim($name);
        }

        return $this->newWithClaim($name, $value);
    }

    /** @param non-empty-string $name */
    private function newWithClaim(string $name, mixed $value): BuilderInterface
    {
        $claims        = $this->claims;
        $claims[$name] = $value;

        return new self(
            $this->encoder,
            $this->claimFormatter,
            $this->headers,
            $claims,
        );
    }

View on GitHub (pinned to 375813049c)