immich-app/immich · critical · Error
The ${name} extension version is ${version}, which mean
Error message
The ${name} extension version is ${version}, which means it is a nightly release.
Please run 'DROP EXTENSION IF EXISTS ${extension}' and switch to a release version.
See https://docs.immich.app/guides/database-queries for how to query the database. What it means
When Immich queries the vector extension version, a value of '0.0.0' signals a nightly/development build rather than a tagged release. Immich deliberately refuses nightly builds because their ABI and behavior are unstable and can corrupt vector indexes. The check fires whenever availableVersion or installedVersion equals 0.0.0 and instructs the operator to DROP and reinstall a release build.
Source
Thrown at server/src/services/database.service.ts:79
if (!current || !semver.satisfies(current, postgresRange)) {
throw new Error(
`Invalid PostgreSQL version. Found ${version}, but needed ${postgresRange}. Please use a supported version.`,
);
}
await this.databaseRepository.withLock(DatabaseLock.Migrations, async () => {
const extension = await this.databaseRepository.getVectorExtension();
const name = EXTENSION_NAMES[extension];
const extensionRange = this.databaseRepository.getExtensionVersionRange(extension);
const extensionVersions = await this.databaseRepository.getExtensionVersions(VECTOR_EXTENSIONS);
const { installedVersion, availableVersion } = extensionVersions.find((v) => v.name === extension) ?? {};
if (!availableVersion) {
throw new Error(messages.notInstalled(name));
}
if ([availableVersion, installedVersion].some((version) => version && semver.eq(version, '0.0.0'))) {
throw new Error(messages.nightlyVersion({ name, extension, version: '0.0.0' }));
}
if (!semver.satisfies(availableVersion, extensionRange)) {
throw new Error(messages.outOfRange({ name, extension, version: availableVersion, range: extensionRange }));
}
if (!installedVersion) {
await this.createExtension(extension);
}
if (installedVersion && semver.gt(availableVersion, installedVersion)) {
await this.updateExtension(extension, availableVersion);
} else if (installedVersion && !semver.satisfies(installedVersion, extensionRange)) {
throw new Error(messages.outOfRange({ name, extension, version: installedVersion, range: extensionRange }));
} else if (installedVersion && semver.lt(availableVersion, installedVersion)) {
throw new Error(messages.invalidDowngrade({ name, extension, availableVersion, installedVersion }));
}
View on GitHub (pinned to 199723261c)
Solutions
- Pin the vector extension image to a release tag (e.g. tensorchord/pgvecto-rs:pg16-v0.3.0 or a tagged pgvector image) instead of nightly.
- Connect to Postgres and run 'DROP EXTENSION IF EXISTS vectors;' (or 'vector') then let Immich recreate it, or recreate it manually with a release version.
- Confirm the release version with: SELECT extversion FROM pg_extension WHERE extname IN ('vector','vectors'); and ensure it is a non-zero semver.
- Restart Immich so bootstrap re-validates the extension.
Example fix
# before image: tensorchord/pgvecto-rs:pg16-nightly # after (pinned release) image: tensorchord/pgvecto-rs:pg16-v0.3.0
Defensive patterns
Strategy: validation
Validate before calling
import pg from 'pg';
const client = new pg.Client({ connectionString: process.env.DB_URL });
await client.connect();
const { rows } = await client.query(
"SELECT extname, extversion FROM pg_extension WHERE extname IN ('vector','vectors');"
);
if (rows.some((r) => r.extversion === '0.0.0' || !/\d+\.\d+\.\d+/.test(r.extversion))) {
throw new Error('Nightly/non-release vector extension detected - install a tagged release');
} Type guard
const isReleaseVersion = (v: string) => !!v && v !== '0.0.0' && /^\d+\.\d+\.\d+$/.test(v);
Try / catch
try {
await app.start();
} catch (e) {
if (/nightly release/.test(String(e?.message))) {
// instruct operator to DROP EXTENSION and pin a release image
logger.fatal(e.message);
process.exit(1);
}
throw e;
} Prevention
- Pin vector extension images to release tags, never 'nightly'.
- Run a pre-deploy check on pg_extension.extversion.
- Keep a runbook entry for DROP EXTENSION / re-CREATE on release images.
When it happens
Trigger: On bootstrap, [availableVersion, installedVersion] contains a version where semver.eq(version, '0.0.0') is true. Happens with nightly tensorchord/pgvecto.rs images, hand-compiled extensions built without a release tag, or some dev Postgres images.
Common situations: Pulling ':nightly'/'-latest' pgvecto.rs tags; building pgvector from a non-release commit; community images that report 0.0.0 as the version string.
Related errors
- The ${name} extension version is ${version}, but Immich only
- The database currently has ${name} ${installedVersion} activ
- The ${name} extension is not available in this Postgres inst
- Invalid PostgreSQL version. Found ${version}, but needed ${p
- No vector extension found. Available extensions: ${VECTOR_EX
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/9762cbc6cad7c875.
Report an issue: GitHub.