{"record":{"id":"30e4571678a6be52","repo":"immich-app/immich","slug":"invalid-system-config","errorCode":null,"errorMessage":"Invalid system config: ","messagePattern":"Invalid system config: ","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"server/src/utils/config.ts","lineNumber":111,"sourceCode":"  const unknownKeys = _.cloneDeep(rawConfig);\n  for (const property of getKeysDeep(defaults)) {\n    unsetDeep(unknownKeys, property);\n  }\n\n  if (!_.isEmpty(unknownKeys)) {\n    logger.warn(`Unknown keys found: ${JSON.stringify(unknownKeys, null, 2)}`);\n  }\n\n  // validate with Zod schema\n  const result = SystemConfigSchema.safeParse(rawConfig);\n  if (!result.success) {\n    const messages = ['Invalid system config: '];\n    for (const issue of result.error.issues) {\n      const path = issue.path.join('.');\n      messages.push(`  - [${path}] ${issue.message}`);\n    }\n    if (configFile) {\n      throw new Error(messages.join('\\n'));\n    }\n    logger.error('Validation error', messages);\n  }\n\n  const config = (result.success ? result.data : rawConfig) as SystemConfig;\n\n  if (config.server.externalDomain.length > 0) {\n    const domain = new URL(config.server.externalDomain);\n\n    const externalDomain =\n      domain.password && domain.username\n        ? `${domain.protocol}//${domain.username}:${domain.password}@${domain.host}`\n        : domain.origin;\n\n    config.server.externalDomain = externalDomain;\n  }\n\n  if (!config.ffmpeg.acceptedVideoCodecs.includes(config.ffmpeg.targetVideoCodec)) {","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/utils/config.ts#L93-L129","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before — config file\n{ \"ffmpeg\": { \"crf\": -5 } }  // out of range\n\n// after\n{ \"ffmpeg\": { \"crf\": 23 } }","handlingStrategy":"validation","validationCode":"// validate the config file against the same schema before boot\nimport { SystemConfigSchema } from 'src/...';\nconst raw = JSON.parse(readFileSync(configFile, 'utf8'));\nconst parsed = SystemConfigSchema.safeParse(raw);\nif (!parsed.success) { for (const i of parsed.error.issues) console.error(i.path.join('.'), i.message); }","typeGuard":"const isSystemConfig = (v: unknown): v is SystemConfig => SystemConfigSchema.safeParse(v).success;","tryCatchPattern":"try { await loadConfig(); }\ncatch (e) { if (e instanceof Error && e.message.startsWith('Invalid system config')) { /* print issues, fall back to DB defaults */ } else throw e; }","preventionTips":["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."],"tags":["config","zod","validation","startup","schema"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}