immich-app/immich · error · Error
Logging cannot be changed while the environment variable IMM
Error message
Logging cannot be changed while the environment variable IMMICH_LOG_LEVEL is set.
What it means
Thrown (plain Error) by SystemConfigService.onConfigValidate when the IMMICH_LOG_LEVEL environment variable is set AND an incoming config update changes the logging block relative to the current one. The env var is treated as authoritative, so log config edits via the admin UI are rejected to avoid contradictory state.
Source
Thrown at server/src/services/system-config.service.ts:55
const configLevel = logging.enabled ? logging.level : false;
const level = envLevel ?? configLevel;
this.logger.setLogLevel(level);
this.logger.log(`LogLevel=${level} ${envLevel ? '(set via IMMICH_LOG_LEVEL)' : '(set via system config)'}`);
this.machineLearningRepository.setup(machineLearning);
}
@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);
}
View on GitHub (pinned to 199723261c)
Solutions
- Unset IMMICH_LOG_LEVEL (remove from docker env / systemd EnvironmentFile) and restart, then change logging via UI.
- Keep IMMICH_LOG_LEVEL and change the env value directly instead of the UI.
- If you must edit via UI, submit a config whose logging block equals the current one (no diff) to pass the _.isEqual check.
Example fix
# before (env pins log level) environment: - IMMICH_LOG_LEVEL=verbose # after (let UI control logging) environment: [] # then restart and edit logging in Admin Settings
Defensive patterns
Strategy: validation
Validate before calling
import { get } from 'node:process';
function canEditLoggingViaUI(): boolean {
return !get('IMMICH_LOG_LEVEL');
}
if (!canEditLoggingViaUI()) { /* change the env var, do not PUT logging via API */ } Try / catch
try { await configApi.update(newConfig); }
catch (e) {
if (e instanceof BadRequestException && /IMMICH_LOG_LEVEL/.test(e.message)) {
// unset the env var, restart, then retry the save
}
} Prevention
- Treat IMMICH_LOG_LEVEL as a temporary debugging knob; unset it in steady state.
- Document which settings are env-overridden so admins do not attempt UI edits.
- Diff old vs new logging block before submit and skip it if env is set.
When it happens
Trigger: PUT /system-config with a modified logging field while the server process has IMMICH_LOG_LEVEL exported. The ConfigValidate event handler throws before any persistence.
Common situations: Operator set IMMICH_LOG_LEVEL=verbose for debugging, then tries to change logging.level through the UI; docker-compose env block pins IMMICH_LOG_LEVEL.
Related errors
- Cannot update configuration while IMMICH_CONFIG_FILE is in u
- Invalid environment variables: \n - [${path}] ${issue.messa
- Invalid worker(s) found: ${workers.join(',')}
- Invalid telemetry found: ${telemetry}
- Invalid SMTP configuration
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/a3717d00eb2c28c3.
Report an issue: GitHub.