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

  1. Use the official Immich image which bundles the geodata file, or run the documented geodata-fetch build step.
  2. Verify resourcePaths.geodata.cities500 resolves to an existing file (check IMMICH_BUILD_DATA).
  3. 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

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


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