Skip to content
DevOps AI ToolKit
Newsletter
All guides
AI for Linux Admins By James Joyner IV · · 9 min read

Linux Error: Argument list too long — Cause, Fix, and Troubleshooting Guide

How to fix the Linux 'Argument list too long' (E2BIG) error: understand ARG_MAX, use xargs and find -exec, split globs, and work around large command lines safely.

  • #linux
  • #troubleshooting
  • #shell

Summary

Argument list too long maps to E2BIG (7). The kernel returns it from the execve() family when the combined size of the command’s arguments and environment exceeds the limit for a single exec. It usually appears when a shell glob (*) expands to thousands of filenames and the resulting command line is too big to hand to the new program. The shell, not the target program, hits the wall.

Common Symptoms

  • rm *, cp * dest/, mv * dir/, or ls *.log | ... fails with /bin/rm: Argument list too long.
  • The same command works in a directory with fewer files.
  • A script that loops over for f in dir/* fails once the directory grows large.
  • Passing a huge list via command substitution (cmd $(find ...)) fails.

Most Likely Causes of the ‘Argument list too long’ Error

Common production causes of the Argument list too long error:

  1. A glob expands to too many files* in a directory with tens of thousands of entries overflows ARG_MAX.
  2. Command substitution injects a huge listprogram $(find . -name '*.tmp') builds one enormous argv.
  3. A large environment shrinks the usable limitARG_MAX covers argv plus envp, so a bloated environment leaves less room for arguments.
  4. Very long individual arguments — a single argument over MAX_ARG_STRLEN (128 KiB) also triggers it, even if the count is small.

Quick Triage

# The hard limit for argv + envp on this host
getconf ARG_MAX

# How many files is the glob about to expand to?
ls -1U /path/to/dir | wc -l

# Reproduce cheaply without running the destructive command
echo /path/to/dir/* | wc -c

If the byte count from echo dir/* | wc -c approaches getconf ARG_MAX (commonly 2097152), the glob is the culprit.

Diagnostic Commands

# ARG_MAX: total bytes for arguments + environment for one execve()
getconf ARG_MAX

# Environment size eats into that budget — check it
env | wc -c

# Count matching files without expanding them onto a command line
find /path/to/dir -maxdepth 1 -type f -name '*.log' | wc -l

# Preview how xargs will batch the list (how many exec calls)
find /path/to/dir -maxdepth 1 -name '*.log' -print0 | xargs -0 --show-limits 2>/dev/null | head

# Confirm which command is failing (shell builtin vs external binary)
type rm

xargs --show-limits prints the effective command-line size it will use and how it plans to split the work — useful for confirming batching before running anything destructive.

Fix / Remediation

The reliable fix is to stop building one giant command line. Use tools that stream the file list instead.

  1. Use find -exec with + (batches arguments up to the limit automatically):

    find /path/to/dir -maxdepth 1 -type f -name '*.log' -exec rm -f {} +
  2. Pipe into xargs (null-delimited to survive spaces/newlines in names):

    find /path/to/dir -maxdepth 1 -type f -name '*.log' -print0 | xargs -0 rm -f
  3. Force smaller batches if a single xargs batch is still too big, or to bound each invocation:

    find /path/to/dir -type f -print0 | xargs -0 -n 1000 rm -f
  4. Loop with a while read for arbitrary per-file work:

    find /path/to/dir -maxdepth 1 -type f -print0 |
      while IFS= read -r -d '' f; do process "$f"; done
  5. For copy/move, use find or rsync instead of a glob:

    find src/ -maxdepth 1 -type f -exec cp -t dest/ {} +
    # or
    rsync -a src/ dest/
  6. Trim the environment if envp is the pressure — unset large exported variables before exec.

Warning: find ... -exec rm -f {} + and xargs rm delete in bulk with no prompt. Dry-run first by replacing the action with echo (-exec echo {} +), and always anchor with -maxdepth/-type f so a wildcard or symlink does not recurse into places you did not intend.

Validation

# The batched command completes without E2BIG
find /path/to/dir -maxdepth 1 -type f -name '*.log' -exec rm -f {} +
ls -1U /path/to/dir | wc -l     # count dropped as expected
echo $?                          # 0

A zero exit status and the expected drop in file count confirm the list was processed in safe batches.

Prevention

  • Never rm */cp */mv * in directories that grow unbounded — reach for find -exec ... + or xargs -0 by default.
  • Shard high-churn directories (e.g. hashed subdirectories) so no single directory holds tens of thousands of entries.
  • Prefer null-delimited pipelines (-print0 | xargs -0) to handle odd filenames safely.
  • Keep the exported environment lean in shells and CI runners so argv has room; remember ARG_MAX covers both.

Final Notes

Argument list too long is E2BIG: the argv-plus-envp for a single execve() exceeded ARG_MAX, almost always because a glob expanded to too many files. The fix is not to raise a limit but to stop constructing one massive command line — stream the file list through find -exec {} + or xargs -0, and shard directories that keep growing. Remember the environment counts against the same budget, so a bloated env can trigger it with fewer arguments than you expect.

Want faster Linux incident response? Use DevOps AI Toolkit to turn production errors into clear diagnostics, remediation steps, and reusable runbooks.

Free download · 368-page PDF

Download the Free 500-Prompt DevOps AI Toolkit

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.