cube-js/cube · error · CubejsHandlerError
Authorization header isn't set
Error message
Authorization header isn't set
What it means
The checkAuth middleware requires an Authorization header (or x-cube-authorization). When no header is present at all and security checks are enforced, Cube throws this 403 Forbidden — the request never reached token verification. The code comments that 401/400 would be more appropriate, but the shipped status is 403.
Source
Thrown at packages/cubejs-api-gateway/src/gateway.ts:2715
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);
if (this.playgroundAuthSecret) {
const systemCheckAuthFn = this.createCheckAuthSystemFn();
return async (ctx, authorization) => {
// TODO: separate two auth workflowsView on GitHub (pinned to 7d981676b3)
Solutions
- Send the header with every request: `Authorization: Bearer <jwt>` or `x-cube-authorization: Bearer <jwt>`.
- Configure the Cube client library with a token or a getToken function so it attaches the header automatically.
- Check proxies/ingress (nginx, API gateways, redirects) aren't stripping the Authorization header; re-add it via header forwarding rules.
- If requests are redirected (http->https), make sure the client sends the header after the final redirect.
Example fix
// before curl http://localhost:4000/cubejs-api/v1/load?query=... // after curl -H "Authorization: $CUBEJS_TOKEN" http://localhost:4000/cubejs-api/v1/load?query=...
Defensive patterns
Strategy: validation
Validate before calling
function ensureAuthHeader(init = {}) {
const headers = new Headers(init.headers || {});
if (!headers.has('Authorization') && !headers.has('x-cube-authorization')) {
headers.set('Authorization', `Bearer ${getToken()}`);
}
return { ...init, headers };
}
fetch('/cubejs-api/v1/load', ensureAuthHeader({ method: 'POST', body })); Type guard
function hasAuthorizationHeader(headers) {
return Boolean(headers && (headers['authorization'] || headers['x-cube-authorization']));
} Try / catch
try {
await cubeApi.load(query);
} catch (e) {
if (e.status === 403 && e.message.includes('Authorization header')) {
// client misconfiguration: attach token then retry once
}
throw e;
} Prevention
- Configure token injection once in the Cube client (token/getToken) instead of per-request
- Add an interceptor/middleware that rejects outgoing requests lacking an Authorization header
- Audit proxies and gateways for header stripping; forward Authorization explicitly
- Prefer x-cube-authorization when intermediaries touch the standard Authorization header
When it happens
Trigger: Calling any Cube REST/GraphQL endpoint without setting `Authorization: <token>` (or `x-cube-authorization`); a proxy or API gateway stripping the Authorization header before forwarding; using a client library instance without a `token`/jwt configured.
Common situations: Browser CORS preflight/redirect dropping custom headers; requests sent through an ingress that sanitizes Authorization; forgetting to configure the token in @cubejs-client after env changes; curl tests that omit the header entirely.
Related errors
- JWT without kid inside headers
- Unable to verify, JWK with kid: "${decoded.header.kid}" not
- Invalid token
- API scope is missing: ${scope}
- Unable to decode JWT key
AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02).
Data as JSON: /api/errors/4e1009bd9cd26fce.
Report an issue: GitHub.