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

  1. Start the microservices service: docker compose up -d immich-microservices (or run 'npm run start:worker' in dev)
  2. Check the microservices container logs for crash causes and fix (ML/Redis connection errors, OOM)
  3. Verify Redis (or the configured queue driver) is reachable from both containers
  4. 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

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)