BookStackApp/BookStack · error · OidcInvalidTokenException

Could not parse out a valid signature within the provided to

Error message

Could not parse out a valid signature within the provided token

What it means

This is the signature-counterpart of the structure check in validateTokenStructure: after header and payload parse, the third dot-separated segment must be a non-empty signature. If empty, OidcInvalidTokenException is thrown. An unsigned/empty-signature token cannot be verified and is rejected early.

Source

Thrown at app/Access/Oidc/OidcJwtWithClaims.php:111

        $this->payload = $claims;
    }

    /**
     * Validate the structure of the given token and ensure we have the required pieces.
     * As per https://datatracker.ietf.org/doc/html/rfc7519#section-7.2.
     *
     * @throws OidcInvalidTokenException
     */
    protected function validateTokenStructure(): void
    {
        foreach (['header', 'payload'] as $prop) {
            if (empty($this->$prop)) {
                throw new OidcInvalidTokenException("Could not parse out a valid {$prop} within the provided token");
            }
        }

        if (empty($this->signature)) {
            throw new OidcInvalidTokenException('Could not parse out a valid signature within the provided token');
        }
    }

    /**
     * Validate the signature of the given token and ensure it validates against the provided key.
     *
     * @throws OidcInvalidTokenException
     */
    protected function validateTokenSignature(): void
    {
        if ($this->header['alg'] !== 'RS256') {
            throw new OidcInvalidTokenException("Only RS256 signature validation is supported. Token reports using {$this->header['alg']}");
        }

        $parsedKeys = array_map(function ($key) {
            try {
                return new OidcJwtSigningKey($key);
            } catch (OidcInvalidKeyException $e) {

View on GitHub (pinned to 18f8469a1c)

Solutions

  1. Ensure the full three-part id_token is transmitted and stored unmodified (check truncation in DB columns/URLs)
  2. Confirm the IdP signs tokens (RS256) and is not issuing alg:none tokens
  3. Obtain a fresh id_token and retry the flow
Defensive patterns

Strategy: validation

Validate before calling

function hasJwtSignature(string $token): bool {
    $parts = explode('.', $token);
    return count($parts) === 3 && $parts[2] !== '';
}

Type guard

function isSignedJwt(mixed $token): bool { return is_string($token) && substr_count($token, '.') === 2 && end(explode('.', $token)) !== ''; }

Try / catch

try {
    $jwt->validate($token);
} catch (\BookStack\Access\Oidc\OidcInvalidTokenException $e) {
    if (str_contains($e->getMessage(), 'signature')) {
        // token is unsigned or truncated; refetch / reject
    }
}

Prevention

When it happens

Trigger: A JWT supplied to the OIDC validation flow whose third segment is empty or absent — e.g. 'xxx.yyy.' — typically an unsecured (alg:none style) or truncated token.

Common situations: Client stripping the signature; provider issuing unsigned tokens (alg none); token truncated in transit or storage (column too short, query-string clipping); pasting only part of the token during testing.

Related errors


AI-assisted analysis of BookStackApp/BookStack@18f8469a1c (2026-09-02). Data as JSON: /api/errors/23994f946f0d8515. Report an issue: GitHub.