Skip to main content

Fixed: "xargs: command line cannot be assembled, too long" on macOS

· 4 min read
Jagdish Kumawat
Founder @ Dewiride

xargs stopped partway through a list with xargs: command line cannot be assembled, too long. The command was only about 250 characters, and the system allows over a million. The limit that matters here is a much smaller one, and it applies only with -I.

What I Was Doing​

I was checking that a list of image addresses all worked, with several curls at a time, on macOS. paths.txt holds one path per line:

Terminal
cat paths.txt | xargs -P 4 -I{} sh -c "curl -s -o /dev/null -w '%{http_code} {}\n' https://strdewiridedevblogsprod.blob.core.windows.net/images/{}"

What I Expected​

A status for every line.

What I Got​

Output
xargs: command line cannot be assembled, too long
200 blog/programming/csharp/fixes/2026/fixed-too-many-connections-02-fixed.webp
200 blog/programming/csharp/fixes/2026/fixed-too-many-connections-01-error.webp

The message xargs: command line cannot be assembled, too long, and only two of the three paths reported.

Two lines worked. The exit code was 1.

What I Checked​

The system's limit on a command line.

Terminal
getconf ARG_MAX
Output
1048576

A million bytes, so it isn't that.

The length of the argument. With {} filled in, the text after sh -c was this many bytes for the first line:

Output
253

That line's path has 75 characters, and the third has 77. So the third one goes over 255.

The man page. man xargs on macOS says of -I: "The resulting arguments, after replacement is done, will not be allowed to grow beyond replsize (or 255 if no -S flag is specified) bytes".

Why It Happens​

With -I, xargs fills {} into your arguments, and each finished argument has a limit of its own, 255 bytes by default on macOS. My whole sh -c string is one argument, and {} appears in it twice.

The Fix​

There are two ways. The first raises the limit, with -S:

Terminal
cat paths.txt | xargs -S 2048 -P 4 -I{} sh -c "curl -s -o /dev/null -w '%{http_code} {}\n' https://strdewiridedevblogsprod.blob.core.windows.net/images/{}"

The second is better. Keep the script fixed, and pass the line to it as its own argument, so the script doesn't change at all:

Terminal
cat paths.txt | xargs -P 4 -I{} sh -c 'curl -s -o /dev/null -w "%{http_code} $1\n" "$0/$1"' https://strdewiridedevblogsprod.blob.core.windows.net/images {}

With sh -c, $0 and $1 are the words after the script. Each argument is now short, and a line with a quote in it can't turn into a command either.

After the Fix​

Output (the file names, with their folders removed)
200 fixed-already-in-transaction-01-error.webp
200 fixed-too-many-connections-01-error.webp
200 fixed-too-many-connections-02-fixed.webp

All three paths reporting status 200.

-S 2048 gave the same three lines.

Common Mistakes​

MistakeWhat happensDo this instead
Looking at ARG_MAXIt's far bigger, and not the limit hereCount one argument
Assuming every line failedLines before the long one have already runRead what did print
Filling {} inside sh -c "..."A line with a quote breaks out of the stringPass it as $1

Troubleshooting​

SymptomLikely causeFix
It works for short lines onlyThis limitUse -S, or $1
-S isn't recognisedAnother xargs, such as GNU'sPass it as $1, which works in both
The line's end is cut off, with no errorA different problemCheck for spaces or quotes in the input

Conclusion​

On macOS, xargs -I limits each finished argument to 255 bytes by default. Raise that with -S, or better, keep {} out of the script and pass it as an argument of its own.

Additional Resources​

  • man xargs, on your own Mac — the -I and -S options.
  • sh -c in POSIX — how the words after the script become $0 and $1.

Stay Updated

Subscribe to our newsletter for the latest tutorials, tech insights, and developer news.

By subscribing, you agree to our privacy policy. Unsubscribe at any time.