immich-app/immich · warning
No microservices worker is connected. Background jobs will…
Error message
No microservices worker is connected. Background jobs will not be processed until one is running.
What it means
The job repository watches for a connected microservices worker (the process that consumes BullMQ background jobs). When the presence transitions to absent, it warns that no worker is consuming jobs. API work continues but background jobs (thumbnailing, ML, backups) will queue indefinitely.
Solutions
- Start the microservices service: docker compose up -d immich-microservices (or run 'npm run start:worker' in dev)
- Check the microservices container logs for crash causes and fix (ML/Redis connection errors, OOM)
- Verify Redis (or the configured queue driver) is reachable from both containers
- Check container resource limits and increase memory if the worker is being OOM-killed
Example fix
// before (docker-compose.yml) — only server defined
services:
immich-server: ...
// after
services:
immich-server: ...
immich-microservices:
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
command: ['start-microservices.sh']
... Defensive patterns
Strategy: retry
Validate before calling
// health check before assuming jobs will run
const redisOk = await new Promise(res => redis.ping().then(() => res(true)).catch(() => res(false)));
const workersPresent = await bullmqQueue.getWorkersCount();
if (!redisOk || workersPresent === 0) {
throw new Error('No job workers connected — start immich-microservices and check Redis');
} Try / catch
try {
await jobRepository.pause(QueueName.ThumbnailGeneration); // or gate submissions
} catch (err) {
alert('No microservices worker: jobs will queue unprocessed');
} Prevention
- Run both immich-server and immich-microservices containers with the same image tag
- Monitor worker count via Redis/BullMQ metrics and alert on zero
- Keep Redis reachable from all containers
- Set memory limits high enough to avoid OOM-killing the worker
When it happens
Trigger: checkWorkers (invoked from watchWorkers polling BullMQ clients) detects that previously-present microservices workers are gone, or none ever connected at startup.
Common situations: Running Immich with only the API server container (microservices container stopped/never started); microservices container crash-looping; Redis connectivity issues preventing worker registration; resource limits (OOM) killing the worker.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
AI-assisted analysis of immich-app/immich@e55ac299a4 (2026-09-15).
Data as JSON: /api/errors/dc4e4cdee7993a37.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/repositories/job.repository.ts:129
clearInterval(this.workerWatcher);
this.workerWatcher = undefined;
}
private async checkWorkers() {
let isPresent: boolean;
try {
const suffix = `:w:${ImmichWorker.Microservices}`;
const workers = await this.getQueue(QueueName.BackgroundTask).getWorkers();
isPresent = workers.some((worker) => worker.rawname?.endsWith(suffix));
} catch {
return;
}
if (this.microservicesPresent !== isPresent) {
if (isPresent) {
this.logger.log('Microservices worker connected.');
} else {
this.logger.warn(
'No microservices worker is connected. Background jobs will not be processed until one is running.',
);
}
}
this.microservicesPresent = isPresent;
}
async run({ name, data }: JobItem) {
const item = this.handlers[name as JobName];
if (!item) {
this.logger.warn(`Skipping unknown job: "${name}"`);
return JobStatus.Skipped;
}
return item.handler(data);
}
setConcurrency(queueName: QueueName, concurrency: number) {View on GitHub (pinned to e55ac299a4)