immich-app/immich · critical · Error
${EXTENSION_NAMES[extension]} extension is not installed
Error message
${EXTENSION_NAMES[extension]} extension is not installed What it means
updateVectorExtension(extension, targetVersion?) fetches installedVersion and availableVersion for the extension. If installedVersion is null the extension is not actually installed in the DB, so it throws <Name> extension is not installed. This is distinct from the extension being available — here it is missing from the database even though an upgrade was attempted.
Source
Thrown at server/src/repositories/database.repository.ts:128
async createExtension(extension: DatabaseExtension): Promise<void> {
this.logger.log(`Creating ${EXTENSION_NAMES[extension]} extension`);
await sql`CREATE EXTENSION IF NOT EXISTS ${sql.raw(extension)} CASCADE`.execute(this.db);
if (extension === DatabaseExtension.VectorChord) {
const dbName = sql.id(await this.getDatabaseName());
await sql`ALTER DATABASE ${dbName} SET vchordrq.probes = 1`.execute(this.db);
await sql`SET vchordrq.probes = 1`.execute(this.db);
}
}
async dropExtension(extension: DatabaseExtension): Promise<void> {
this.logger.log(`Dropping ${EXTENSION_NAMES[extension]} extension`);
await sql`DROP EXTENSION IF EXISTS ${sql.raw(extension)}`.execute(this.db);
}
async updateVectorExtension(extension: VectorExtension, targetVersion?: string): Promise<void> {
const [{ availableVersion, installedVersion }] = await this.getExtensionVersions([extension]);
if (!installedVersion) {
throw new Error(`${EXTENSION_NAMES[extension]} extension is not installed`);
}
if (!availableVersion) {
throw new Error(`No available version for ${EXTENSION_NAMES[extension]} extension`);
}
targetVersion ??= availableVersion;
if (!semver.diff(installedVersion, targetVersion)) {
return;
}
await Promise.all([
this.db.schema.dropIndex(VectorIndex.Clip).ifExists().execute(),
this.db.schema.dropIndex(VectorIndex.Face).ifExists().execute(),
]);
await sql`ALTER EXTENSION ${sql.raw(extension)} UPDATE TO ${sql.lit(targetVersion)}`.execute(this.db);
await Promise.all([this.reindexVectors(VectorIndex.Clip), this.reindexVectors(VectorIndex.Face)]);View on GitHub (pinned to 199723261c)
Solutions
- Create the extension: CREATE EXTENSION IF NOT EXISTS <extension>; in the Immich database, then restart.
- Verify you are connected to the correct database/schema.
- Re-run the startup/migration flow that calls updateVectorExtension.
Defensive patterns
Strategy: validation
Validate before calling
const res = await sql`SELECT extversion FROM pg_extension WHERE extname = '${ext}'`;
if (res.rows.length === 0) {
throw new Error(`${ext} not installed; run CREATE EXTENSION first.`);
} Prevention
- Run CREATE EXTENSION for the vector extension during DB provisioning.
- Confirm the same DB/schema Immich connects to actually has the extension.
- Avoid manual DROP EXTENSION outside of documented migration steps.
When it happens
Trigger: Triggering a vector-extension upgrade (e.g. during a migration/startup that calls updateVectorExtension) when the extension has not been CREATE EXTENSION'd in the current database, or was dropped.
Common situations: Extension was available (so the earlier check passed) but never created in this DB; a prior dropExtension removed it; connected to a different database/schema than expected.
Related errors
- No vector extension found. Available extensions: ${VECTOR_EX
- No available version for ${EXTENSION_NAMES[extension]} exten
- Migration "${missing[1]}" was already applied to this databa
- Invalid PostgreSQL version. Found ${version}, but needed ${p
- Invalid CLIP dimension size: ${dimSize}
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/283374380f475029.
Report an issue: GitHub.