immich-app/immich · error · Error
The API key header can only be set using setApiKey().
Error message
The API key header can only be set using setApiKey().
What it means
The Immich SDK guards the x-api-key header so it can only be set through the dedicated setApiKey() (or init({ apiKey })) entry point. setHeader and setHeaders route every key through assertNoApiKey, which throws a plain Error when the lowercased key equals x-api-key. This prevents callers from accidentally bypassing the key-management path or overwriting the API key with an unrelated header value.
Source
Thrown at packages/sdk/src/index.ts:47
};
export const setHeader = (key: string, value: string) => {
assertNoApiKey(key);
defaults.headers = defaults.headers || {};
defaults.headers[key] = value;
};
export const setHeaders = (headers: Record<string, string>) => {
defaults.headers = defaults.headers || {};
for (const [key, value] of Object.entries(headers)) {
assertNoApiKey(key);
defaults.headers[key] = value;
}
};
const assertNoApiKey = (headerKey: string) => {
if (headerKey.toLowerCase() === 'x-api-key') {
throw new Error('The API key header can only be set using setApiKey().');
}
};
export const getAssetOriginalPath = (id: string) => `/assets/${id}/original`;
export const getAssetThumbnailPath = (id: string) => `/assets/${id}/thumbnail`;
export const getAssetPlaybackPath = (id: string) =>
`/assets/${id}/video/playback`;
export const getUserProfileImagePath = (userId: string) =>
`/users/${userId}/profile-image`;
export const getPeopleThumbnailPath = (personId: string) =>
`/people/${personId}/thumbnail`;
View on GitHub (pinned to 199723261c)
Solutions
- Call setApiKey(apiKey) instead of setting the header yourself.
- If using init(), pass the key via the apiKey field and keep headers free of x-api-key.
- Filter the x-api-key key out of any dynamic header object before calling setHeaders.
Example fix
// before
setHeaders({ 'x-api-key': apiKey, 'accept': 'application/json' });
// after
setApiKey(apiKey);
setHeaders({ 'accept': 'application/json' }); Defensive patterns
Strategy: validation
Validate before calling
// before calling setHeaders, strip any api-key variant
const SAFE_HEADERS = Object.fromEntries(
Object.entries(headers).filter(
([k]) => k.toLowerCase() !== 'x-api-key',
),
);
setHeaders(SAFE_HEADERS);
setApiKey(apiKey); Type guard
const isApiKeyHeader = (key: string): boolean => key.toLowerCase() === 'x-api-key';
Try / catch
try {
setHeaders(headers);
} catch (e) {
if ((e as Error).message.includes('setApiKey')) {
setApiKey(headers['x-api-key']);
const { 'x-api-key': _omit, ...rest } = headers;
setHeaders(rest);
} else throw e;
} Prevention
- Always set the API key via setApiKey / init({ apiKey }), never via setHeaders.
- Treat the headers object as metadata-only and filter api-key variants before passing it in.
- Centralize SDK init in one place so no other code touches headers directly.
When it happens
Trigger: Calling setHeaders({ 'x-api-key': '...' }), setHeaders({ 'X-API-KEY': '...' }), setHeader('X-Api-Key', value), or passing headers: { 'x-api-key': ... } to init(). The check is case-insensitive, so any capitalization triggers it.
Common situations: Migrating from a custom fetch wrapper where you set auth headers manually; copy-pasting a header object that includes the api key; trying to override the key per-request via setHeaders.
Related errors
- Failed to call host function "${String(name)}", received ${r
- Missing JWT Token
- Invalid JWT Token
- Failed to read helmet file: ${helmetFile}
- Invalid environment variables: \n - [${path}] ${issue.messa
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/0455d7731b437bce.
Report an issue: GitHub.