immich-app/immich · critical · UnsupportedPostgresError

Unsupported PostgreSQL version: ${databaseVersion}

Error message

Unsupported PostgreSQL version: ${databaseVersion}

What it means

Thrown as UnsupportedPostgresError(databaseVersion) by DatabaseBackupService during restore setup. The detected PostgreSQL version must satisfy semver '>=14.0.0 <19.0.0' AND both databaseMajorVersion and databaseSemver must be non-null; otherwise the dump's PG version is considered unsupported for restore. The message interpolates the detected version string.

Source

Thrown at server/src/services/database-backup.service.ts:210

            '--single-transaction',
            // exit with non-zero code on error
            '--set',
            'ON_ERROR_STOP=on',
          );
        }

        args.push(
          // used for progress monitoring
          '--echo-all',
          '--output=/dev/null',
        );
        break;
      }
    }

    if (!databaseMajorVersion || !databaseSemver || !semver.satisfies(databaseSemver, '>=14.0.0 <19.0.0')) {
      this.logger.error(`Database Restore Failure: Unsupported PostgreSQL version: ${databaseVersion}`);
      throw new UnsupportedPostgresError(databaseVersion);
    }

    return {
      bin: `/usr/lib/postgresql/${databaseMajorVersion}/bin/${bin}`,
      args,
      databaseUsername,
      databasePassword: isUrlConnection ? new URL(databaseConfig.url).password : databaseConfig.password,
      databaseVersion,
      databaseMajorVersion,
    };
  }

  async createDatabaseBackup(filenamePrefix: string = ''): Promise<string> {
    this.logger.debug(`Database Backup Started`);

    const { bin, args, databasePassword, databaseVersion, databaseMajorVersion } =
      await this.buildPostgresLaunchArguments('pg_dump');

View on GitHub (pinned to 199723261c)

Solutions

  1. Run a supported PostgreSQL major version (14, 15, 16, 17, or 18) for both source and target.
  2. Re-check pg_restore / psql discovery so the version is parsed correctly (non-empty databaseVersion).
  3. If the backup came from a now-unsupported version, dump on a supported version first, then restore.

Example fix

// before
const cfg = await backupService.getRestoreConfig();
await backupService.restoreDatabaseBackup(filename);

// after
const semver = require('semver');
const v = await databaseRepository.getPostgresVersion();
const coerced = semver.coerce(v);
if (!coerced || !semver.satisfies(coerced, '>=14.0.0 <19.0.0')) {
  throw new Error(`Cannot restore on PostgreSQL ${v}; use a 14–18 release.`);
}
await backupService.restoreDatabaseBackup(filename);
Defensive patterns

Strategy: validation

Validate before calling

const v = await databaseRepository.getPostgresVersion();
const c = require('semver').coerce(v);
if (!c || !require('semver').satisfies(c, '>=14.0.0 <19.0.0')) {
  throw new Error(`PostgreSQL ${v} is unsupported for restore; use 14–18.`);
}

Type guard

function isSupportedPg(v: string | null): boolean {
  if (!v) return false;
  const c = require('semver').coerce(v);
  return !!c && require('semver').satisfies(c, '>=14.0.0 <19.0.0');
}

Prevention

When it happens

Trigger: Restoring a database backup when the running PostgreSQL is <14 or >=19, or when the version could not be parsed (major/semver came back null/undefined).

Common situations: Upgrading the PG container to a v19 build before Immich supports it; a custom/old PG image (<=13) used for restore; a version-detection failure returning an empty string so coerce() yields null.

Related errors


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