gitroomhq/postiz-app · error · HttpException

invalid_token

invalid_token

Error message

{ error: 'invalid_token', error_description: 'Bearer token required' }

What it means

Returned as HTTP 401 invalid_token from getUserInfo when the Authorization header is missing or does not contain a valid Bearer token (extractBearerToken returns null). The endpoint requires 'Authorization: Bearer <token>'.

Source

Thrown at libraries/nestjs-libraries/src/database/prisma/oauth/oauth.service.ts:355

  async getOrgByOAuthToken(token: string) {
    const encrypted = AuthService.fixedEncryption(token);
    return this._oauthRepository.findByAccessToken(encrypted);
  }

  async getUserInfo(authorization?: string) {
    if (!enableOidcEmailClaims()) {
      throw new HttpException(
        {
          error: 'not_found',
          error_description: 'OIDC email claims are not enabled',
        },
        HttpStatus.NOT_FOUND
      );
    }

    const token = extractBearerToken(authorization);
    if (!token) {
      throw new HttpException(
        { error: 'invalid_token', error_description: 'Bearer token required' },
        HttpStatus.UNAUTHORIZED
      );
    }

    const authorizationRecord = await this.getOrgByOAuthToken(token);
    if (!authorizationRecord) {
      throw new HttpException(
        { error: 'invalid_token', error_description: 'Token is invalid or revoked' },
        HttpStatus.UNAUTHORIZED
      );
    }

    if (authorizationRecord.oauthApp.clientId !== openAiOAuthClientId()) {
      throw new HttpException(
        {
          error: 'insufficient_scope',
          error_description:

View on GitHub (pinned to 0f1647f749)

Solutions

  1. Set the header exactly: Authorization: Bearer <accessToken>
  2. Confirm you're using the access_token from the token exchange response (not id_token or code)
  3. Check for 'Bearer ' prefix capitalization and single space, and that the token string isn't undefined

Example fix

// before
fetch(userInfoEndpoint, { headers: { Authorization: tokens.id_token } });
// after
fetch(userInfoEndpoint, { headers: { Authorization: `Bearer ${tokens.access_token}` } });
Defensive patterns

Strategy: validation

Validate before calling

const token = extractBearer(authorization);
if (!token) throw new Error('Authorization: Bearer <access_token> header required');

Type guard

const hasBearerToken = (h?: string): boolean => /^Bearer \S+$/.test(h ?? '');

Try / catch

try { return await getUserInfo(auth); } catch (e) { if (e?.response?.data?.error === 'invalid_token' && !auth?.startsWith('Bearer ')) { return getUserInfo(`Bearer ${auth}`); } throw e; }

Prevention

When it happens

Trigger: Calling the user info endpoint with no Authorization header, a non-Bearer scheme (Basic, token), an empty token, or a malformed header like 'Bearer' with no value.

Common situations: Client reads the token from the wrong JSON field (e.g. access_token vs id_token); token not persisted between requests; header built manually with typos; passing the whole token response object instead of the string.

Related errors


AI-assisted analysis of gitroomhq/postiz-app@0f1647f749 (2026-08-27). Data as JSON: /api/errors/99ee937238235593. Report an issue: GitHub.