immich-app/immich · error
Invalid telemetry found
Error message
Invalid telemetry found: ${telemetry} What it means
IMMICH_TELEMETRY_INCLUDE/EXCLUDE are parsed into telemetry-name sets and each resulting value is validated against TELEMETRY_TYPES. If an included-minus-excluded telemetry name is not a known ImmichTelemetry value, startup throws with the invalid name.
Solutions
- Use only valid ImmichTelemetry values (see the enum in server/src): typically 'api', 'io', 'host' — set IMMICH_TELEMETRY_INCLUDE=all to enable everything instead of guessing names
- Fix casing/pluralization: IMMICH_TELEMETRY_INCLUDE=api,host
- If you meant OpenTelemetry-style tracing, that is not an immich telemetry kind — remove the token or use IMMICH_TELEMETRY_INCLUDE=all
- Check the enum for the installed immich version in case names changed
Example fix
// before IMMICH_TELEMETRY_INCLUDE=metrics,tracing // after IMMICH_TELEMETRY_INCLUDE=all # or IMMICH_TELEMETRY_INCLUDE=api,io,host
Defensive patterns
Strategy: validation
Validate before calling
const TELEMETRY = new Set(['api', 'io', 'host']);
const include = process.env.IMMICH_TELEMETRY_INCLUDE;
if (include && include !== 'all') {
const bad = include.split(',').filter(t => !TELEMETRY.has(t));
if (bad.length) throw new Error(`Unknown telemetry: ${bad.join(',')} — valid: ${[...TELEMETRY].join(',')} or 'all'`);
} Type guard
const isTelemetry = (t: string): t is 'api' | 'io' | 'host' => ['api', 'io', 'host'].includes(t);
Try / catch
try { start(); } catch (e) { if ((e as Error).message.startsWith('Invalid telemetry found:')) { console.error(`Use IMMICH_TELEMETRY_INCLUDE=all or valid kinds (api, io, host). ${(e as Error).message}`); process.exit(1); } throw e; } Prevention
- Use IMMICH_TELEMETRY_INCLUDE=all instead of enumerating names you are unsure of
- Confirm exact kind names from the ImmichTelemetry enum in your immich version
- Avoid OpenTelemetry-flavored names (metrics/tracing) — they are not valid values here
- Keep telemetry flags consistent between INCLUDE and EXCLUDE to avoid surprises
When it happens
Trigger: IMMICH_TELEMETRY_INCLUDE (or EXCLUDE after 'all' handling) contains a token not in the ImmichTelemetry enum, e.g. 'metrics', 'otel', 'tracing', or a case-mismatched 'API' instead of the valid values (e.g. 'api', 'io', 'host').
Common situations: Users enabling OpenTelemetry by guess-writing names; pluralizing ('hosts'); copying flags from another project's telemetry config; version drift where a telemetry kind was renamed or removed in immich.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Invalid environment variables:
- Invalid worker(s) found
- error instanceof Error ? error.message : error
- {error.message}
- Failed to decode redis options
AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15).
Data as JSON: /api/errors/5f99a1280bd7c937.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/repositories/config.repository.ts:225
const redisUrl = dto.REDIS_URL;
if (redisUrl && redisUrl.startsWith('ioredis://')) {
try {
redisConfig = JSON.parse(Buffer.from(redisUrl.slice(10), 'base64').toString());
} catch (error) {
throw new Error('Failed to decode redis options', { cause: error });
}
}
const includedTelemetries =
dto.IMMICH_TELEMETRY_INCLUDE === 'all'
? new Set(Object.values(ImmichTelemetry))
: asSet<ImmichTelemetry>(dto.IMMICH_TELEMETRY_INCLUDE, []);
const excludedTelemetries = asSet<ImmichTelemetry>(dto.IMMICH_TELEMETRY_EXCLUDE, []);
const telemetries = setDifference(includedTelemetries, excludedTelemetries);
for (const telemetry of telemetries) {
if (!TELEMETRY_TYPES.has(telemetry)) {
throw new Error(`Invalid telemetry found: ${telemetry}`);
}
}
const databaseConnection: DatabaseConnectionParams = dto.DB_URL
? { connectionType: 'url', url: dto.DB_URL }
: {
connectionType: 'parts',
host: dto.DB_HOSTNAME || 'database',
port: dto.DB_PORT || 5432,
username: dto.DB_USERNAME || 'postgres',
password: dto.DB_PASSWORD || 'postgres',
database: dto.DB_DATABASE_NAME || 'immich',
ssl: dto.DB_SSL_MODE || undefined,
};
let vectorExtension: VectorExtension | undefined;
if (dto.DB_VECTOR_EXTENSION) {
switch (dto.DB_VECTOR_EXTENSION) {View on GitHub (pinned to e55ac299a4)