immich-app/immich · error · BadRequestException

Cannot update configuration while IMMICH_CONFIG_FILE is in u

Error message

Cannot update configuration while IMMICH_CONFIG_FILE is in use

What it means

Thrown (as BadRequestException) by SystemConfigService.updateSystemConfig when IMMICH_CONFIG_FILE is set. With a config file in use, the database is no longer the source of truth, so writes via the admin API are refused to prevent divergence.

Source

Thrown at server/src/services/system-config.service.ts:62

  @OnEvent({ name: 'ConfigUpdate', server: true })
  onConfigUpdate({ newConfig }: ArgOf<'ConfigUpdate'>) {
    this.onConfigInit({ newConfig });
    clearConfigCache();
  }

  @OnEvent({ name: 'ConfigValidate' })
  onConfigValidate({ newConfig, oldConfig }: ArgOf<'ConfigValidate'>) {
    const { logLevel } = this.configRepository.getEnv();
    if (logLevel && !_.isEqual(toPlainObject(newConfig.logging), oldConfig.logging)) {
      throw new Error('Logging cannot be changed while the environment variable IMMICH_LOG_LEVEL is set.');
    }
  }

  async updateSystemConfig(dto: SystemConfigDto): Promise<SystemConfigDto> {
    const { configFile } = this.configRepository.getEnv();
    if (configFile) {
      throw new BadRequestException('Cannot update configuration while IMMICH_CONFIG_FILE is in use');
    }

    const oldConfig = await this.getConfig({ withCache: false });

    try {
      await this.eventRepository.emit('ConfigValidate', { newConfig: toPlainObject(dto), oldConfig });
    } catch (error) {
      this.logger.warn(`Unable to save system config due to a validation error: ${error}`);
      throw new BadRequestException(error instanceof Error ? error.message : error);
    }

    const newConfig = await this.updateConfig(dto);

    await this.eventRepository.emit('ConfigUpdate', { newConfig, oldConfig });

    return mapConfig(newConfig);
  }

View on GitHub (pinned to 199723261c)

Solutions

  1. Edit the file referenced by IMMICH_CONFIG_FILE directly and restart the server.
  2. If you want UI-managed config, unset IMMICH_CONFIG_FILE and restart (DB config then applies).
  3. Confirm the env var is not set accidentally by a base image or compose override.

Example fix

# before: file-based config blocks UI
environment:
  - IMMICH_CONFIG_FILE=/config/immich.json
# after: UI-managed (remove the var, restart)
environment: []
Defensive patterns

Strategy: validation

Validate before calling

import { get } from 'node:process';
function isConfigFileMode(): boolean { return Boolean(get('IMMICH_CONFIG_FILE')); }
if (isConfigFileMode()) { /* edit the file, do not call PUT /system-config */ }

Try / catch

try { await configApi.update(newConfig); }
catch (e) {
  if (e instanceof BadRequestException && /IMMICH_CONFIG_FILE/.test(e.message)) {
    // switch to file edits or unset the env var and restart
  }
}

Prevention

When it happens

Trigger: PUT /system-config (or any admin UI save) while the server boots with IMMICH_CONFIG_FILE pointing at a JSON/YAML config.

Common situations: Operator migrated to file-based config but the admin UI is still used to tweak settings; CI deploys set IMMICH_CONFIG_FILE and a post-deploy script calls the config API.

Related errors


AI-assisted analysis of immich-app/immich@199723261c (2026-08-12). Data as JSON: /api/errors/c41ebe0aa57e473e. Report an issue: GitHub.