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/, orls *.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:
- A glob expands to too many files —
*in a directory with tens of thousands of entries overflowsARG_MAX. - Command substitution injects a huge list —
program $(find . -name '*.tmp')builds one enormous argv. - A large environment shrinks the usable limit —
ARG_MAXcovers argv plus envp, so a bloated environment leaves less room for arguments. - 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.
-
Use
find -execwith+(batches arguments up to the limit automatically):find /path/to/dir -maxdepth 1 -type f -name '*.log' -exec rm -f {} + -
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 -
Force smaller batches if a single
xargsbatch is still too big, or to bound each invocation:find /path/to/dir -type f -print0 | xargs -0 -n 1000 rm -f -
Loop with a
while readfor arbitrary per-file work:find /path/to/dir -maxdepth 1 -type f -print0 | while IFS= read -r -d '' f; do process "$f"; done -
For copy/move, use
findorrsyncinstead of a glob:find src/ -maxdepth 1 -type f -exec cp -t dest/ {} + # or rsync -a src/ dest/ -
Trim the environment if envp is the pressure — unset large exported variables before exec.
Warning:
find ... -exec rm -f {} +andxargs rmdelete in bulk with no prompt. Dry-run first by replacing the action withecho(-exec echo {} +), and always anchor with-maxdepth/-type fso 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 forfind -exec ... +orxargs -0by 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_MAXcovers both.
Related Errors
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.
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.