Skip to content
🎉 Launch sale:50% off everything over $22 — automatically applied at checkout· ends Aug 2Shop the sale →
DevOps AI ToolKit
Newsletter
All guides
AI for Automation By James Joyner IV · · 8 min read Last reviewed Jul 2026

GNU Parallel Error: 'parallel: command not found' — Cause, Fix, and Troubleshooting Guide

Quick answer

Fix 'parallel: command not found' — GNU parallel missing, the wrong moreutils parallel installed, PATH issues, and minimal CI images.

  • #automation
  • #troubleshooting
  • #gnu-parallel
Free toolkit

Fixing errors like this? Get 500 free DevOps AI prompts

500 copy-paste AI prompts for the stack you actually run — one PDF, free.

Overview

parallel: command not found means the shell walked every directory in PATH and never found an executable named parallel. In an automation context this usually surfaces the first time a script that fans work out with GNU parallel runs on a fresh host or a minimal CI image where the package was never installed:

$ ./resize-images.sh
./resize-images.sh: line 12: parallel: command not found
make: *** [Makefile:8: resize] Error 127

Exit code 127 is the shell’s standard signal for “command not found,” so a wrapper or CI step that checks the exit status will fail the whole job.

There is a second, more insidious variant of this problem: parallel is installed, but it is the wrong one. Two completely different programs ship a binary called parallel — GNU parallel and the parallel from the moreutils package. They take incompatible arguments, so a script written for GNU parallel that lands on a host with moreutils fails with a confusing usage error instead of command not found:

$ parallel -j4 convert {} {.}.png ::: *.jpg
parallel: invalid option -- 'j'
Usage: parallel [OPTIONS] command -- arguments

Symptoms

  • parallel: command not found and an exit status of 127 from the shell.
  • The script works on a developer laptop but fails in CI, a container, or on a freshly provisioned host.
  • parallel is present but rejects :::, -j, or {} with invalid option (moreutils is installed instead of GNU parallel).
  • GNU parallel runs but prints a citation notice to stderr on every invocation, cluttering logs.
# Confirm the shell really cannot find it
command -v parallel || echo "not on PATH"
not on PATH

Common Root Causes

1. The package is simply not installed

The most common case, especially on minimal base images (debian:slim, alpine, ubi-minimal) that ship almost nothing.

dpkg -l parallel 2>/dev/null | grep '^ii' || echo "package not installed"
package not installed

2. The moreutils parallel is installed instead of GNU parallel

Both packages provide /usr/bin/parallel. If moreutils is installed (it is a common dependency of other tooling), its parallel shadows or replaces the GNU one, and GNU-parallel syntax breaks.

parallel --version 2>&1 | head -1
parallel: invalid option -- '-'

GNU parallel answers --version with a real version banner; the moreutils version does not understand it.

3. PATH does not include the install location

On macOS with Homebrew, or when parallel is installed to /usr/local/bin or ~/.local/bin, a stripped-down PATH in cron or a systemd unit will not find it.

echo "$PATH"
/usr/bin:/bin

4. Minimal CI image without the package

CI runners built from slim images do not include parallel by default, so a pipeline that runs fine locally fails on the runner.

5. Installed for a different user / not on the service account’s PATH

A binary installed into myuser’s home is invisible to a cron job or systemd service running as a different account.

How to Diagnose

Start by asking the shell exactly what it resolves — or fails to resolve:

which parallel; command -v parallel; type parallel
parallel not found

If nothing is found, confirm whether the package exists at all and which package owns any parallel on disk:

# Which package provides /usr/bin/parallel, if it exists?
dpkg -S "$(command -v parallel 2>/dev/null)" 2>/dev/null || echo "no parallel binary owned by any package"
ls -l /usr/bin/parallel 2>/dev/null || echo "no /usr/bin/parallel"
no /usr/bin/parallel

If a parallel is present, determine which implementation it is — this is the make-or-break check:

parallel --version 2>&1 | head -1
GNU parallel 20221122

A GNU parallel <date> banner means you have the right tool. Anything else — an invalid option error or a Usage: parallel [OPTIONS] command -- arguments line — means moreutils is installed instead.

Finally, in cron or systemd, print the effective PATH the job actually runs with, since it differs from an interactive shell:

# Inside the job, log the environment
systemctl show -p ExecStart myjob.service
env | grep -i path

Fixes

Install GNU parallel

Debian / Ubuntu:

sudo apt-get update && sudo apt-get install -y parallel

RHEL / Fedora / Rocky (parallel lives in EPEL on RHEL-family):

sudo dnf install -y epel-release   # RHEL/Rocky/Alma only
sudo dnf install -y parallel

macOS:

brew install parallel

Alpine (CI images):

apk add --no-cache parallel

Verify you got the GNU implementation, not moreutils:

parallel --version | head -1
GNU parallel 20221122

Resolve a moreutils conflict

On Debian/Ubuntu the two packages conflict over /usr/bin/parallel and are managed by the alternatives system. If moreutils won, install GNU parallel and repoint the alternative:

sudo apt-get install -y parallel
# If /usr/bin/parallel still points at moreutils, remove moreutils' parallel
# or select GNU parallel explicitly:
sudo update-alternatives --list parallel 2>/dev/null

If you need both packages, keep moreutils but call GNU parallel by an absolute path, or install it into a directory earlier on PATH. Do not assume parallel on an unknown host is GNU parallel — always guard with a --version check in your script.

Fix PATH for cron / systemd

Set an explicit PATH in the unit or crontab rather than relying on the caller’s environment:

# /etc/systemd/system/myjob.service
[Service]
Environment=PATH=/usr/local/bin:/usr/bin:/bin
ExecStart=/opt/jobs/resize-images.sh
# crontab
PATH=/usr/local/bin:/usr/bin:/bin
*/10 * * * * /opt/jobs/resize-images.sh

Suppress the citation notice

GNU parallel prints a one-time academic citation notice to stderr, which pollutes automation logs. Silence it permanently by running the built-in citation registration once as the service account:

parallel --citation
# type "will cite" at the prompt, or:
mkdir -p ~/.parallel && echo 'will cite' > ~/.parallel/will-cite

You can also pass --will-cite on each invocation to skip the notice without writing the file:

parallel --will-cite -j4 convert {} '{.}.png' ::: *.jpg

What to Watch Out For

  • Never assume parallel is GNU parallel. On a shared or unknown host it may be moreutils. Add a parallel --version | grep -q '^GNU parallel' preflight check to your script and fail loudly with a clear message if it is missing or wrong.
  • command not found returns exit 127, not the job’s own failure code. Wrappers and CI that only test $? != 0 will treat it as a generic failure — grep the log for command not found to distinguish a missing tool from a real job error.
  • The citation notice goes to stderr, so it can mask real errors in log scanners that alert on any stderr output. Register will-cite on every account that runs the tool, including the systemd/cron service account, not just your login shell.
  • Alpine and other minimal images may need the package added in the Dockerfile; installing it interactively in a running container does not persist to the next build.
  • PATH in non-interactive shells is minimal. A binary in /usr/local/bin or ~/.local/bin that works interactively can be invisible to cron — always set PATH explicitly for scheduled work.
Free download · 368-page PDF

Fixed it? Get 500 Automation & DevOps AI prompts — free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.

Did this fix your issue?

Free download · 368-page PDF

Get 500 Battle-Tested DevOps AI Prompts — Free

500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.

  • 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
  • Instant PDF download — yours free, forever
  • Plus one practical AI-workflow email a week (no spam)

Single opt-in · unsubscribe anytime · no spam.