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 reserves the 'x-api-key' header for setApiKey() only. setHeader/setHeaders refuse any attempt to set a header named x-api-key (case-insensitive) so the credential can't be duplicated or overridden inconsistently by user code.

Solutions

  1. Remove the x-api-key header from setHeader/setHeaders calls and call setApiKey(value) instead.
  2. Filter x-api-key out of any header object sourced from config/env before passing to setHeaders.
  3. Rename the env/config field so it feeds setApiKey, not a generic header list.

Example fix

// before
sdk.setHeaders({ 'x-api-key': process.env.IMMICH_API_KEY! });
// after
sdk.setApiKey(process.env.IMMICH_API_KEY!);
Defensive patterns

Strategy: validation

Validate before calling

const RESERVED = ['x-api-key'];
const safeHeaders = Object.fromEntries(
  Object.entries(userHeaders).filter(([k]) => !RESERVED.includes(k.toLowerCase()))
);
sdk.setHeaders(safeHeaders);

Try / catch

try {
  sdk.setHeaders(headers);
} catch (e) {
  if (String(e).includes('setApiKey')) {
    sdk.setApiKey((headers as any)['x-api-key']);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling sdk.setHeader('x-api-key', ...) or passing { 'x-api-key': ... } (any casing: X-API-Key, etc.) to setHeaders; commonly done by users who treat the SDK like raw fetch and copy auth-header code from curl examples.

Common situations: Migrating code from a plain fetch wrapper to the Immich SDK, wiring headers from environment config that already contains the key, or bulk-copying a defaults.headers object that includes x-api-key.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15). Data as JSON: /api/errors/0455d7731b437bce. Report an issue: GitHub.

Appendix: source

Thrown at packages/sdk/src/index.ts:48

};

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 jsonOnly =
  (impl?: typeof fetch): typeof fetch =>
  async (input, options) => {
    const response = await (impl ?? fetch)(input, options);

    const expectsJson = new Headers(options?.headers)
      .get('accept')
      ?.includes('json');
    if (!expectsJson || response.status === 204) {
      return response;
    }

    const contentType = response.headers.get('content-type');
    if (!contentType?.includes('json')) {
      throw new MalformedResponseError(

View on GitHub (pinned to e55ac299a4)