Informix Error -7
-7 Arg list too long.
An operating-system error code with the meaning shown was unexpectedly returned to the database server. Look for other operating-system error messages that might give more information. If the error recurs, see the information about trapping errors in your Administrator's Guide or Reference to acquire additional diagnostics. Contact IBM Informix Technical Support with the diagnostic information.
Oninit® Troubleshooting Guidance
This is an operating-system error number, not an Informix diagnosis.
The same errno is returned by many different operations, so on its own it says what the operating system refused, not what Informix was trying to do. Informix will usually have reported a more specific error alongside it — in the message log, in the SQL or ISAM error pair, or in the accompanying assert failure — and that error normally defines the real cause far more precisely than the errno does. Find it before diagnosing from this number alone.
This matters less than it used to. Later versions of the engine trap many of these conditions and report them as specific Informix errors naming the operation, the object and the context, so a bare errno in this range is increasingly a sign of an older version, an unusual code path, or a failure early in startup before the better reporting is available. If you are seeing one on a current version, the more specific error is worth looking for even harder.
Operating-System Meaning
errno 7 is E2BIG — Argument list too long. A program could not be executed because the arguments handed to it exceeded the kernel's limit.
Two details make this error make sense, and both are commonly missed:
It is argv plus the environment. The limit covers the combined size of the argument list and the exported environment, along with their pointers. A large environment reduces the room available for arguments before a single character of the command line is counted — and Informix environments are large by nature (INFORMIXDIR, INFORMIXSERVER, ONCONFIG, INFORMIXSQLHOSTS, PATH, LD_LIBRARY_PATH, the DB* and GL_* locale variables, plus whatever the application layers on).
The limit is not a fixed number on Linux. Since kernel 2.6.23 it is derived from the stack limit — roughly RLIMIT_STACK / 4 — with a separate cap of 128 KB on any single argument. So the same command can succeed on one host and fail on another purely because ulimit -s differs, which makes this error look mysteriously host-specific.
The overwhelmingly common trigger is shell glob expansion: command /path/* where the directory holds tens of thousands of entries. The shell expands the pattern before exec(), so the failure belongs to the expansion, not to the program.
What This Means in Informix
The pattern to look for is a script operating on a directory that grows without bound. Informix estates produce several:
- Logical log backup directories. The classic case — a housekeeping or compression job running
gzip /backups/logs/*against a directory that has accumulated months of files. - Archive and
onbarstaging directories cleaned with a glob. $INFORMIXDIR/tmp, which accumulates sqexplain and session files.- Unload and export directories from
dbexportor external tables. SYSTEM()calls from SPL, 4GL or ESQL/C where the command line is built from data — a list of keys, filenames or values pulled from a query. This is the dangerous one, because the command length depends on the result set and works fine until the day the query returns more rows.ALARMPROGRAMor a backup wrapper invoked with a generated argument list.- A bloated environment under a wrapper that exports everything it can, leaving little headroom for any arguments at all.
Common Causes
- A glob expanding to too many files — by far the most frequent.
- A command line built from query results that has grown past the limit.
- A large environment consuming the budget, often after a wrapper or profile change rather than anything in the command.
- A small
ulimit -son this host relative to where the script was developed or previously ran. - A single argument over 128 KB — usually a generated list passed as one quoted string.
Diagnostic Checks
Establish the limit on this host, and the two things consuming it:
getconf ARG_MAX
ulimit -s # ARG_MAX is roughly this / 4 on Linux
env | wc -c # environment size in bytes
env | wc -l # number of variables
Measure what the command would actually expand to, without running it:
echo /backups/logs/* | wc -c # size of the expanded argument list
ls /backups/logs | wc -l # how many entries
Compare that against getconf ARG_MAX. If it is the same order of magnitude, you have found it.
Find which directories are capable of causing this:
for d in /backups/logs "$INFORMIXDIR/tmp" /backups/archive /informix/unload; do
[ -d "$d" ] && printf '%8d %s\n' "$(ls -1 "$d" 2>/dev/null | wc -l)" "$d"
done | sort -rn
If the environment is the suspect, see what is in it:
env | awk '{ print length($0), $0 }' | sort -rn | head -10
echo "$PATH" | tr ':' '\n' | wc -l
For a command built at runtime by an application, log it before it executes rather than inferring — in SPL, 4GL or ESQL/C, write the constructed string to a file or the message log and check its length:
wc -c /tmp/generated_command.txt
To confirm the failure is the exec rather than the program:
strace -f -e trace=execve <command> 2>&1 | tail -5
# look for: execve(...) = -1 E2BIG (Argument list too long)
Solutions / Resolution
- Replace the glob with something that batches.
xargsandfind -exec … +split the work into as manyexec()calls as needed and never hit the limit:
Note# instead of: gzip /backups/logs/* find /backups/logs -maxdepth 1 -type f ! -name '*.gz' -print0 | xargs -0 -r gzip # or: find /backups/logs -maxdepth 1 -type f ! -name '*.gz' -exec gzip {} +-exec … +rather than-exec … \;— the+form batches, the\;form runs one process per file and is correct but slow. - Fix the accumulation, not just the command. A logical log backup directory holding tens of thousands of files is a retention problem; batching the compression makes the error go away while the directory keeps growing. Set a retention policy and prune.
- Trim the environment where it is the constraint. A wrapper that exports the entire estate's variables into every child process is worth revisiting.
- Raise the stack limit only as a stopgap, and knowing what it does:
ulimit -s unlimitedbefore the command raisesARG_MAXwith it on Linux. This is a workaround, not a fix, and it will not survive into contexts that set their own limits. - For generated command lines, stop passing data as arguments. Write the list to a file and have the program read it — that has no size limit and is more robust in every other respect too.
- Split a single oversized argument. The 128 KB per-string cap is separate from the total, and no amount of stack limit will raise it.
Examples
A housekeeping job over a log backup directory
$ ls /backups/logs | wc -l
84213
$ echo /backups/logs/* | wc -c
3452901
$ getconf ARG_MAX
2097152
$ gzip /backups/logs/*
-bash: /usr/bin/gzip: Argument list too long
The expanded list is 3.4 MB against a 2 MB limit. The fix in the script:
find /backups/logs -maxdepth 1 -type f ! -name '*.gz' -print0 \
| xargs -0 -r gzip
…and separately, a retention policy, because 84,000 logical log backups is the actual problem.
Works on one host, fails on another
# host A — where the script was written
$ ulimit -s ; getconf ARG_MAX
unlimited
2097152
# host B — where it fails
$ ulimit -s ; getconf ARG_MAX
2048
524288
Identical script, identical data, different stack limit. Nothing about the command changed. This is the presentation that sends people looking for a difference in the data when the difference is in limits.conf.
A command built from a result set
An SPL procedure constructing a shell command from a query:
LET cmd = "/informix/scripts/process_batch.sh " || key_list;
SYSTEM cmd;
Where key_list is accumulated from a SELECT, the command length is a function of how many rows matched. It works in test with a few hundred keys and fails in production with fifty thousand. Passing a filename instead of the keys removes the limit entirely:
-- write the keys to a file via UNLOAD, then:
LET cmd = "/informix/scripts/process_batch.sh -f /informix/tmp/keys.unl";
SYSTEM cmd;
The environment, not the arguments
$ env | wc -c
1987431
$ getconf ARG_MAX
2097152
$ /informix/scripts/archive.sh
-bash: /informix/scripts/archive.sh: Argument list too long
A command with almost no arguments, failing because the environment has consumed nearly the whole budget — typically a wrapper exporting everything, or a variable holding a very large generated value. env | awk '{print length($0), $0}' | sort -rn | head names the culprit immediately.
Platform Note
errno 7 is E2BIG on Linux, AIX, Solaris, HP-UX and the BSD-derived systems — stable, so the number is reliable.
The limit itself is anything but portable, and this is a case where a script's behaviour genuinely changes on being moved:
| Platform | ARG_MAX behaviour |
|---|---|
| Linux (≥ 2.6.23) | Derived from RLIMIT_STACK / 4; single argument capped at 128 KB |
| Solaris | Fixed, typically 1 MB (getconf ARG_MAX) |
| AIX | Fixed, typically 2 MB |
| HP-UX | Fixed, commonly smaller — worth checking explicitly |
| Older Linux (< 2.6.23) | Fixed at 128 KB |
Always read the value with getconf ARG_MAX on the host in question rather than assuming. On Linux, also read ulimit -s, because the two are linked and the stack limit is what actually varies between hosts in the same estate.
Related Errors / Related Topics
- -8 — Exec format error. The other reason an
exec()fails, and the one to check if the argument list is plainly small. - -12 — Not enough memory, also seen when process creation fails, though for a different reason.
- -2 — No such file or directory, worth ruling out when a generated command line may also contain a bad path.
Where -7 appears in scheduled housekeeping, treat the directory size as the finding rather than the failing command. The same directory will eventually break ls, backup scripts and monitoring alike, and retention is the durable fix.