immich-app/immich · error
Machine learning request
Error message
Machine learning request '${JSON.stringify(config)}' failed for all URLs What it means
The machine learning repository attempts the prediction request against each configured ML URL in order, logging a warning per failed URL. If every URL fails (connection refused, timeout, HTTP errors), it throws with the serialized request config, indicating the ML service is unreachable or unhealthy rather than a problem with the request itself.
Solutions
- Verify the ML service is up and reachable: curl http://machine-learning:3003/ping from the server container
- Check/fix MACHINE_LEARNING_URL(S) env — it must match the ML container's host:port and Docker network
- Inspect ML container logs for startup/model-load crashes and fix (e.g. increase memory, fix model name)
- Ensure request payload matches the running ML server's supported schema/version (align Immich server and ML image versions)
Example fix
// before (docker-compose.yml, server env) MACHINE_LEARNING_URL=http://127.0.0.1:3003 // after — use the compose service name MACHINE_LEARNING_URL=http://immich-machine-learning:3003
Defensive patterns
Strategy: retry
Validate before calling
for (const url of mlUrls) {
try { const r = await fetch(`${url}/ping`); if (!r.ok) throw new Error(String(r.status)); }
catch { throw new Error(`ML service unreachable at ${url}; check container/network`); }
} Type guard
function mlUrlLooksValid(url: string): boolean {
try { const u = new URL(url); return u.protocol === 'http:' || u.protocol === 'https:'; } catch { return false; }
} Try / catch
try {
const result = await mlRepo.predict(url, config, input);
} catch (e) {
if ((e as Error).message.includes('failed for all URLs')) {
logger.warn('ML unreachable; queueing for retry', { config });
await jobRepo.add({ name: JobName.X, data: input }); // retry via queue with backoff
} else throw e;
} Prevention
- Health-check the ML /ping endpoint in readiness probes before serving traffic
- Use compose service DNS names, not localhost, for cross-container ML URLs
- Keep server and ML image versions aligned and monitor ML container logs/memory
When it happens
Trigger: All entries in MACHINE_LEARNING_URLS are unreachable at request time: ML container down, wrong host/port, network policy blocking the call, or the ML service crashing on the request — after which the loop falls through to the final throw.
Common situations: ML container not started or crashed (OOM during model load); misconfigured MACHINE_LEARNING_URL (e.g. 127.0.0.1 when ML runs in another container); Docker network misconfiguration; ML model failing on a particular image so every attempt errors.
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- Invalid model name
- Machine learning request to
- Unknown CLIP model
- Asset has no embedding
- Attempted to clear cache, but rmtree is not safe on this…
AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15).
Data as JSON: /api/errors/d6a876ffe6612af9.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/repositories/machine-learning.repository.ts:187
]) {
try {
const response = await fetch(new URL('predict', url), { method: 'POST', body: formData });
if (response.ok) {
this.setHealthy(url, true);
return response.json();
}
this.logger.warn(
`Machine learning request to "${url}" failed with status ${response.status}: ${response.statusText}`,
);
} catch (error: Error | unknown) {
this.logger.warn(`Machine learning request to "${url}" failed`, error);
}
this.setHealthy(url, false);
}
throw new Error(`Machine learning request '${JSON.stringify(config)}' failed for all URLs`);
}
async detectFaces(imagePath: string, { modelName, minScore }: FaceDetectionOptions) {
const request = {
[ModelTask.FACIAL_RECOGNITION]: {
[ModelType.DETECTION]: { modelName, options: { minScore } },
[ModelType.RECOGNITION]: { modelName },
},
};
const response = await this.predict<FacialRecognitionResponse>({ imagePath }, request);
return {
imageHeight: response.imageHeight,
imageWidth: response.imageWidth,
faces: response[ModelTask.FACIAL_RECOGNITION],
};
}
async encodeImage(imagePath: string, { modelName }: MachineLearningConfig['clip']) {View on GitHub (pinned to e55ac299a4)