immich-app/immich · critical · Error
Invalid system config:
Error message
Invalid system config:
What it means
Thrown by the config loader (server/src/utils/config.ts) when the raw system config fails Zod validation against SystemConfigSchema AND it was loaded from a config file (configFile set). The error message aggregates every Zod issue with its path and message. When there is no config file, validation errors are only logged, not thrown.
Source
Thrown at server/src/utils/config.ts:111
const unknownKeys = _.cloneDeep(rawConfig);
for (const property of getKeysDeep(defaults)) {
unsetDeep(unknownKeys, property);
}
if (!_.isEmpty(unknownKeys)) {
logger.warn(`Unknown keys found: ${JSON.stringify(unknownKeys, null, 2)}`);
}
// validate with Zod schema
const result = SystemConfigSchema.safeParse(rawConfig);
if (!result.success) {
const messages = ['Invalid system config: '];
for (const issue of result.error.issues) {
const path = issue.path.join('.');
messages.push(` - [${path}] ${issue.message}`);
}
if (configFile) {
throw new Error(messages.join('\n'));
}
logger.error('Validation error', messages);
}
const config = (result.success ? result.data : rawConfig) as SystemConfig;
if (config.server.externalDomain.length > 0) {
const domain = new URL(config.server.externalDomain);
const externalDomain =
domain.password && domain.username
? `${domain.protocol}//${domain.username}:${domain.password}@${domain.host}`
: domain.origin;
config.server.externalDomain = externalDomain;
}
if (!config.ffmpeg.acceptedVideoCodecs.includes(config.ffmpeg.targetVideoCodec)) {View on GitHub (pinned to 199723261c)
Solutions
- Read the full error message — each line lists the field path and the Zod issue; fix each one in the config file.
- Compare your config file against the current SystemConfig schema/default template for the installed Immich version.
- Temporarily remove the config file to boot with DB-stored defaults, then re-apply changes field by field.
- Validate the file with a JSON/YAML linter before deploying.
Example fix
// before — config file
{ "ffmpeg": { "crf": -5 } } // out of range
// after
{ "ffmpeg": { "crf": 23 } } Defensive patterns
Strategy: validation
Validate before calling
// validate the config file against the same schema before boot
import { SystemConfigSchema } from 'src/...';
const raw = JSON.parse(readFileSync(configFile, 'utf8'));
const parsed = SystemConfigSchema.safeParse(raw);
if (!parsed.success) { for (const i of parsed.error.issues) console.error(i.path.join('.'), i.message); } Type guard
const isSystemConfig = (v: unknown): v is SystemConfig => SystemConfigSchema.safeParse(v).success;
Try / catch
try { await loadConfig(); }
catch (e) { if (e instanceof Error && e.message.startsWith('Invalid system config')) { /* print issues, fall back to DB defaults */ } else throw e; } Prevention
- Lint/validate the config file in CI against SystemConfigSchema before deploying.
- Keep a version-pinned reference config and diff yours against it on upgrades.
- Remove the config file to boot with DB defaults when unsure.
When it happens
Trigger: Immich started with IMMICH_CONFIG_FILE pointing at a JSON/YAML file whose values fail schema validation: wrong types, out-of-range numbers, unknown enum values, or structurally invalid nested objects.
Common situations: Editing the config file by hand and introducing a typo or invalid enum (e.g. ffmpeg.accel set to an unsupported hardware acceleration, or a negative CRF); upgrading Immich where a config field was renamed/removed and the old file no longer parses; copying a config snippet from an incompatible version.
Related errors
- Invalid environment variables: \n - [${path}] ${issue.messa
- Invalid worker(s) found: ${workers.join(',')}
- Invalid telemetry found: ${telemetry}
- Invalid SMTP configuration
- Unknown CLIP model: ${newConfig.machineLearning.clip.modelNa
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/30e4571678a6be52.
Report an issue: GitHub.