immich-app/immich · critical · Error
Geodata file ${cities500} not found
Error message
Geodata file ${cities500} not found What it means
During geodata import (loadCities500), Immich resolves resourcePaths.geodata.cities500 and checks existsSync(cities500). If the file is missing it throws Error('Geodata file <path> not found') before attempting the stream import. The cities500 dataset is required to populate the places/geocoding feature.
Source
Thrown at server/src/repositories/map.repository.ts:272
)`.execute(manager);
await manager.schema.dropTable('geodata_places').execute();
await manager.schema.alterTable('geodata_places_tmp').renameTo('geodata_places').execute();
});
await this.db.schema
.createIndex('IDX_geodata_gist_earthcoord')
.on('geodata_places')
.using('gist')
.expression(sql`ll_to_earth_public(latitude, longitude)`)
.execute();
await this.loadCities500(admin1, admin2);
await this.createGeodataIndices();
}
private async loadCities500(admin1Map: Map<string, string>, admin2Map: Map<string, string>) {
const { resourcePaths } = this.configRepository.getEnv();
const cities500 = resourcePaths.geodata.cities500;
if (!existsSync(cities500)) {
throw new Error(`Geodata file ${cities500} not found`);
}
this.logger.log(`Starting geodata import`);
const startTime = performance.now();
const input = createReadStream(cities500, { highWaterMark: 512 * 1024 * 1024 });
let bufferGeodata = [];
const lineReader = readLine.createInterface({ input });
let count = 0;
let futures = [];
for await (const line of lineReader) {
const lineSplit = line.split('\t');
if ((lineSplit[7] === 'PPLX' && lineSplit[8] !== 'AU') || lineSplit[7] === 'PPLH') {
continue;
}
const geoData = {View on GitHub (pinned to 199723261c)
Solutions
- Use the official Immich image which bundles the geodata file, or run the documented geodata-fetch build step.
- Verify resourcePaths.geodata.cities500 resolves to an existing file (check IMMICH_BUILD_DATA).
- Place cities500.txt in the expected geodata directory and re-run the import.
Defensive patterns
Strategy: validation
Validate before calling
import { existsSync } from 'node:fs';
const cities500 = resolveGeodataPath('cities500');
if (!existsSync(cities500)) {
throw new Error(`Geodata file missing: ${cities500}; rebuild image with geodata bundle.`);
} Prevention
- Use the official image which bundles cities500.
- In custom images, run the geodata-fetch build step and assert the file exists.
- Verify IMMICH_BUILD_DATA points to the folder containing the geodata bundle.
When it happens
Trigger: Triggering the geodata import (map/geocoding bootstrap) when the packaged cities500.txt is absent from the build geodata resource folder.
Common situations: Broken/incomplete build or container image missing the geodata bundle; custom IMMICH_BUILD_DATA/resource path pointing to a folder without the file; geodata download step skipped during image build.
Related errors
- Failed to read helmet file: ${helmetFile}
- Failed to read: "${externalPath} (${internalPath}) - ${docsM
- Failed to create "${externalPath} - ${docsMessage}"
- Failed to write "${externalPath} - ${docsMessage}"
- Invalid environment variables: \n - [${path}] ${issue.messa
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/8fed490b4f258e00.
Report an issue: GitHub.