cube-js/cube · error · CubejsHandlerError

Invalid token

Error message

Invalid token

What it means

This is the generic wrapper: when the configured checkAuth function (default JWT verification or a user-supplied `checkAuth`) throws for a presented token and the gateway runs with security checks enforced (production mode, no dev/prod toggle disabling them), Cube rethrows it as a 403 'Invalid token'. The original error is attached as `cause`, so the underlying reason (bad signature, expiry, missing kid, etc.) is inside it.

Source

Thrown at packages/cubejs-api-gateway/src/gateway.ts:2710

            403,
            'Forbidden',
            `Unable to verify, JWK with kid: "${decoded.header.kid}" not found`
          );
        }

        return verifyToken(auth, jwk);
      };
    }

    return async (req, auth) => {
      if (auth) {
        try {
          req.securityContext = await checkAuthFn(auth);
          req.signedWithPlaygroundAuthSecret =
            Boolean(internalOptions?.isPlaygroundCheckAuth) && hasDevTokenScope(req.securityContext);
        } catch (e: any) {
          if (this.enforceSecurityChecks) {
            throw new CubejsHandlerError(403, 'Forbidden', 'Invalid token', e);
          }
        }
      } else if (this.enforceSecurityChecks) {
        // @todo Move it to 401 or 400
        throw new CubejsHandlerError(403, 'Forbidden', 'Authorization header isn\'t set');
      }

      return {
        securityContext: req.securityContext
      };
    };
  }

  protected createCheckAuthFn(options: ApiGatewayOptions): PreparedCheckAuthFn {
    const mainCheckAuthFn = options.checkAuth
      ? this.wrapCheckAuth(options.checkAuth)
      : this.createDefaultCheckAuth(options.jwt);

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Inspect the error's `cause` to get the real reason (e.g. 'jwt expired', 'invalid signature') and fix that underlying issue.
  2. Re-generate the token with the correct current signing secret and algorithm configured for the Cube instance.
  3. Verify client clock and token `exp`/`nbf` claims; issue tokens with a reasonable validity window.
  4. If using a custom checkAuth, add logging/fix its exception path so valid tokens don't throw.
  5. For local development only, run with dev mode enabled where enforceSecurityChecks is false (never in production).

Example fix

// before
const token = jwt.sign(payload, OLD_SECRET, { expiresIn: '1s' });
// after
const token = jwt.sign(payload, process.env.CUBEJS_API_SECRET, { expiresIn: '1h' });
Defensive patterns

Strategy: try-catch

Validate before calling

function tokenLooksValid(token, secret) {
  try { jwt.verify(token, secret); return true; } catch { return false; }
}
if (!tokenLooksValid(myToken, process.env.CUBEJS_API_SECRET)) {
  myToken = refreshToken(); // before calling Cube
}

Type guard

function isCubeForbiddenError(e) {
  return !!e && typeof e.status === 'number' && e.status === 403 && typeof e.message === 'string';
}

Try / catch

try {
  const rs = await cubeApi.load(query);
} catch (e) {
  if (isCubeForbiddenError(e) && e.message === 'Invalid token') {
    const reason = e.cause?.message; // real cause: 'jwt expired', 'invalid signature', etc.
    await refreshSession();
    return cubeApi.load(query); // single retry after token refresh
  }
  throw e;
}

Prevention

When it happens

Trigger: Any Authorization header whose token fails the checkAuth function — expired JWT, wrong signing key, malformed token, custom checkAuth throwing — while `enforceSecurityChecks` is true (i.e. not running with CUBEJS_DEV_MODE-style disabled checks).

Common situations: Expired tokens after session timeout; mismatched JWT secret after rotating CUBEJS_API_SECRET or moving environments; clock skew between token issuer and Cube server; custom checkAuth rejecting valid users due to a bug; forgetting that in dev mode the same token succeeds but production enforces checks.

Understand the failure class

Related errors


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/bb59842557400fc3. Report an issue: GitHub.