Performance & Virtualization

A service cannot create more threads or processes

Fork or thread creation fails while memory remains available. Check cgroup task counts and ancestor limits before raising TasksMax or blaming the application.

On this page
  1. Symptoms & scope
  2. Possible causes
  3. Diagnose safely
  4. Evidence-guided next steps
  5. References & review
  6. Related problems

Symptoms & scope

  • The kernel reports fork rejected by pids controller.
  • A worker pool or shell cannot create additional tasks.

Relevant environment

Linux cgroup v2 pids controller and systemd TasksMax; threads count toward the task budget.

Recognizable messages (synthetic examples)
kernel: cgroup: fork rejected by pids controller in /system.slice/example.service

A task budget blocked creation; inspect local and parent limits and actual thread demand.

Possible causes

These are possible explanations, not a confirmed diagnosis. Several independent faults can coexist.

  • The service or an ancestor may reach pids.max; the count includes threads, not just process leaders.
  • An application may leak threads or create excessive workers; RLIMIT_NPROC is a separate possible constraint.

Diagnose safely

Run one command at a time in the relevant session. Read the explanation first. Uppercase placeholders need your own values; tools and privileges vary by distribution. These commands are displayed here and never executed by the website.

Check 1

Replace the affected unit; reads current task count and configured limits.

systemctl show example.service -p ControlGroup -p TasksCurrent -p TasksMax -p LimitNPROC

Interpret the result: TasksMax is cgroup-based, while LimitNPROC is user-account-based. A parent pids limit can block a service below its local maximum.

Check 2

Replace the path with ControlGroup under /sys/fs/cgroup; reads existing cgroup v2 files.

cat /sys/fs/cgroup/system.slice/example.service/pids.current /sys/fs/cgroup/system.slice/example.service/pids.max /sys/fs/cgroup/system.slice/example.service/pids.events

Interpret the result: Compare current count with the limit and max-event deltas. Counts can temporarily exceed a limit after policy changes; thread creation still cannot violate the enforced budget.

Evidence-guided next steps

Bound worker and thread creation

If counts grow with connections or jobs and fail to fall afterward, cap the application's documented worker pool and investigate lifecycle leaks. Reduce accepted concurrency rather than restarting blindly.

Precautions: Stopping or restarting workers may interrupt requests. Preserve thread-count evidence before reset.

Recovery / rollback: Restore prior application concurrency only within the intended task budget; recover interrupted jobs using their supported mechanism.

Did this solution help you?

Share this solution#

Right-size the intended task budget

If legitimate thread demand exceeds an accidental low TasksMax, increase the finite budget for this service or its limiting parent. Recheck memory cost and host headroom while keeping a protective bound.

Precautions: Raising only the child cannot override its parent. Unlimited tasks can amplify a runaway worker loop.

Recovery / rollback: Restore the recorded task budgets at their original hierarchy levels and compare the same connection load.

Did this solution help you?

Share this solution#

References & review

This guide was prepared from primary project or distribution sources and reviewed on the date shown. This is an editorial source check, not evidence that a fix was reproduced on your hardware. Diagnostic log examples are synthetic fixtures. Version-dependent details must be checked against your installed release.