thedotmack/claude-mem · error
Unauthorized
Unauthorized
Error message
Missing API key (Authorization: Bearer <key> or X-Api-Key: <key>)
What it means
401 from the Postgres auth middleware when no API key is present on the request. Same contract as the SQLite variant: the key must arrive as Authorization: Bearer <key> or X-Api-Key: <key>; when local-dev is off (or localDevTeamId unset and dev mode inactive) and rawKey is empty, the middleware rejects with 401 before touching Postgres.
Source
Thrown at src/server/middleware/postgres-auth.ts:91
&& hasLoopbackHostHeader(req)
&& !hasForwardedClientHeaders(req)
) {
const ctx: AuthContext = {
userId: null,
organizationId: null,
teamId: options.localDevTeamId ?? null,
projectId: null,
scopes: ['local-dev'],
apiKeyId: null,
mode: 'local-dev',
};
req.authContext = ctx;
next();
return;
}
if (!rawKey) {
res.status(401).json({
error: 'Unauthorized',
message: 'Missing API key (Authorization: Bearer <key> or X-Api-Key: <key>)',
});
return;
}
const verified = await verifyPostgresApiKey(pool, rawKey, options.requiredScopes ?? []);
if (!verified) {
res.status(403).json({ error: 'Forbidden', message: 'Invalid API key or insufficient scope' });
return;
}
const ctx: AuthContext = {
userId: null,
organizationId: null,
teamId: verified.teamId,
projectId: verified.projectId,
scopes: verified.scopes,View on GitHub (pinned to e2d1df569a)
Solutions
- Attach the key: Authorization: Bearer <key> or X-Api-Key: <key> on every request.
- Verify the client's key env var is set in the runtime that actually issues requests.
- Ensure proxies/ingress forward the Authorization header to the app.
- Use local-dev mode only for local runs, and configure localDevTeamId if you need unauthenticated local requests.
Example fix
// before
const res = await fetch(`${base}/v1/events`, { method: 'POST', body }); // 401
// after
const res = await fetch(`${base}/v1/events`, {
method: 'POST',
headers: { 'X-Api-Key': process.env.API_KEY!, 'Content-Type': 'application/json' },
body,
}); Defensive patterns
Strategy: validation
Validate before calling
const apiKey = process.env.API_KEY;
if (!apiKey) {
throw new Error('API_KEY unset; postgres-auth will reject with 401 before hitting the database');
}
const headers = { Authorization: `Bearer ${apiKey}` }; Type guard
interface UnauthorizedBody { error: string; message: string }
function isMissingKey401(res: Response, body: unknown): boolean {
return res.status === 401 && typeof body === 'object' && body !== null &&
(body as UnauthorizedBody).error === 'Unauthorized';
} Prevention
- Validate required env vars in a startup checklist.
- Ensure ingress/proxy forwards Authorization to the app.
- Use one shared HTTP client so headers cannot be forgotten per call.
When it happens
Trigger: Any request to a postgres-backed route (e.g. /v1/events) with neither auth header; a gateway or sidecar that drops the Authorization header; client configured with an unset key env var so it sends nothing.
Common situations: Deploying against Postgres for the first time and reusing scripts written for local-dev mode where no header was needed; .env missing API_KEY in the container; ingress stripping Authorization unless explicitly forwarded.
Understand the failure class
Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.
Related errors
AI-assisted analysis of thedotmack/claude-mem@e2d1df569a (2026-08-20).
Data as JSON: /api/errors/97d99b06c78f819d.
Report an issue: GitHub.