Informix Error -24
-24 Too many open files.
An operating-system error code with the meaning shown was unexpectedly returned to the database server. This error probably reflects a limit that was configured in your operating system. Look for other operating-system error messages that might give more 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 24 is EMFILE — Too many open files. This process has reached its own descriptor limit. The host may have enormous headroom; the limit that bit is per-process.
That is the distinction from -23, and it decides where the fix goes:
-24 EMFILE |
-23 ENFILE |
|
|---|---|---|
| Scope | One process | The whole host |
| Controlled by | RLIMIT_NOFILE — ulimit -n |
fs.file-max |
Raising fs.file-max helps? |
No | Yes |
| Usual culprit | This process, or its limit | Possibly something else on the host |
The official text is right that this "probably reflects a limit that was configured in your operating system" — and the useful work is finding which configured limit, because on a modern host there are at least three that can be in force and they override each other.
The check that actually matters
ulimit -nin your shell tells you nothing about the running server.
A process inherits its limits when it starts. A limit raised afterwards — in limits.conf, in a profile, in a systemd unit — does not reach a process already running. So the administrator checks ulimit -n, sees 65536, and concludes the limit cannot be the problem, while oninit has been running since before that change with 1024.
The only authoritative source is the process itself:
cat /proc/<pid>/limits | grep -i 'open files'
Check that before anything else on this error.
What This Means in Informix
The engine's descriptor consumption is substantial and grows with the estate:
- Every chunk — a large instance with many dbspaces can hold hundreds
- Every client connection
- Virtual processors and their own files
- Message log, backup devices, temporary files
Growth is usually gradual, which is why this error tends to arrive after months of nothing changing: chunks added one at a time, connection pools widened slightly, another application sharing the host.
Where the limit comes from
Three places, in increasing order of how often they are missed:
/etc/security/limits.confandlimits.d/— the traditional place, applied through PAM at login.- The systemd unit, if the instance is started that way.
LimitNOFILEon the unit overrideslimits.confentirely, because systemd does not go through the PAM login path. - The container's limits, which may be lower than either.
The systemd case is a recurring theme across this range — the same override applies to TasksMax on -11, LimitMEMLOCK on -12 and LimitFSIZE on -27. If Informix is started by systemd, the unit is the authoritative place for all of them, and limits.conf can be perfectly correct and entirely ignored.
Client-side
EMFILE is just as likely in a client. An application server holding a wide connection pool, or a batch program that leaks connections, reaches its own limit and fails to connect — which presents to users as a database problem and is not one.
Common Causes
- A limit raised after the process started, so the running engine never saw it.
- A systemd unit without
LimitNOFILE, silently overriding a correctlimits.conf. - Gradual growth in chunks, sessions or instances on a host.
- A descriptor leak in the engine's client or in an application.
- A container limit below the host's.
- A connection storm consuming descriptors faster than they close.
- A client application at its own limit, misreported as a server problem.
Diagnostic Checks
Read the running process's actual limit. Nothing else matters until this is known:
pgrep -a oninit
cat /proc/$(pgrep -o oninit)/limits | grep -i 'open files'
# Max open files 1024 4096 files <- soft, hard
Then how many it is using:
ls /proc/$(pgrep -o oninit)/fd | wc -l
# every oninit process, current against limit
for p in $(pgrep oninit); do
used=$(ls /proc/"$p"/fd 2>/dev/null | wc -l)
lim=$(awk '/Max open files/ {print $4}' /proc/"$p"/limits)
printf 'pid %-8s used %-8s limit %s\n' "$p" "$used" "$lim"
done
A process at or near its limit is the confirmation. Compare with the host total to be sure this is -24 and not -23:
cat /proc/sys/fs/file-nr # host-wide: allocated / free / max
Host nowhere near its max, process at its limit → -24.
Find which limit is in force. Check all three sources, because they disagree more often than not:
ulimit -n ; ulimit -Hn # this shell only
grep -rn nofile /etc/security/limits.conf /etc/security/limits.d/ 2>/dev/null
systemctl show <informix-unit> -p LimitNOFILE -p LimitNOFILESoft
cat /sys/fs/cgroup/... 2>/dev/null # container
Establish whether the consumption is reasonable for the estate:
onstat -d | grep -c '^[0-9]' # chunks
onstat -g ses | wc -l # sessions
onstat -g ntu | head
grep -nE 'NUMCPUVPS|NETTYPE' "$INFORMIXDIR/etc/$ONCONFIG"
Roughly: chunks plus sessions plus overhead. A count far above that suggests a leak rather than growth.
Group a process's descriptors by target — a long run of the same file or socket is a leak:
ls -l /proc/<pid>/fd | awk '{print $NF}' | sort | uniq -c | sort -rn | head
For a client application, check its process rather than the server's:
cat /proc/<app-pid>/limits | grep -i 'open files'
ls /proc/<app-pid>/fd | wc -l
ls -l /proc/<app-pid>/fd | grep -c socket
Solutions / Resolution
- Read
/proc/<pid>/limitsfirst. If the running limit is lower than the configured one, the answer is that the process predates the change and no further investigation is needed. - Raise the limit in every place that applies, not just the traditional one:
# /etc/security/limits.d/informix.conf ifxprod soft nofile 65536 ifxprod hard nofile 131072
followed by# systemd unit — REQUIRED if the instance starts this way [Service] LimitNOFILE=65536:131072systemctl daemon-reload. - Restart the instance for the new limit to take effect — a running process keeps the limits it was given.
- In an emergency, raise the limit on the live process rather than taking an outage. On Linux:
This is a stopgap that does not survive a restart, and it must be accompanied by fixing the configuration. Verify it took withprlimit --pid <pid> --nofile=65536:131072cat /proc/<pid>/limits. - If the profile suggests a leak, fix the leak. Raising the limit against a leak only postpones the failure.
- For containers, set it in the pod or container specification.
- If the client is at fault, fix the client's limit or its connection handling. Nothing on the server will help.
- Add monitoring on used-against-limit for the engine's processes. This error is entirely predictable from that ratio.
Examples
The limit was raised and the server never saw it
$ ulimit -n
65536
$ grep nofile /etc/security/limits.d/informix.conf
ifxprod soft nofile 65536
ifxprod hard nofile 131072
$ cat /proc/$(pgrep -o oninit)/limits | grep -i 'open files'
Max open files 1024 4096 files
$ ps -o lstart= -p $(pgrep -o oninit)
Mon Mar 11 08:14:22 2026
Everything the administrator checked is correct. The engine has been running since March with the limits in force at that time. The configuration change never reached it, and will not until a restart — or a prlimit as a stopgap.
systemd overriding a correct limits.conf
$ grep nofile /etc/security/limits.d/informix.conf
ifxprod soft nofile 65536
$ systemctl show informix -p LimitNOFILE
LimitNOFILE=1024
$ cat /proc/$(pgrep -o oninit)/limits | grep -i 'open files'
Max open files 1024 1024 files
limits.conf is not consulted for a systemd-started service. The unit is the authoritative place, and it is at the default. The same trap applies to TasksMax (-11) and LimitMEMLOCK (-12) on the same unit — worth fixing all three together while the file is open.
The client, not the server
$ cat /proc/sys/fs/file-nr
28416 0 1048576
$ cat /proc/$(pgrep -o oninit)/limits | grep -i 'open files'
Max open files 65536 131072 files
$ ls /proc/$(pgrep -o oninit)/fd | wc -l
4188
$ cat /proc/8891/limits | grep -i 'open files'
Max open files 1024 4096 files
$ ls /proc/8891/fd | wc -l
1021
The host is fine and the engine is comfortable. The application at PID 8891 is three descriptors from its own limit. Users report that the database is refusing connections; the database is doing nothing of the sort.
Platform Note
errno 24 is EMFILE on Linux, AIX, Solaris, HP-UX and the BSD-derived systems — stable, so the number is reliable.
Reading and setting a running process's limits is not portable:
| Task | Linux | Solaris | AIX |
|---|---|---|---|
| Running process's limit | /proc/<pid>/limits |
plimit <pid> |
ulimit at start; procfiles |
| Change a live process | prlimit --pid |
plimit -n <soft>,<hard> <pid> |
not generally available |
| Configured limit | limits.conf, systemd |
project.max-file-descriptor |
/etc/security/limits |
| Current usage | ls /proc/<pid>/fd |
pfiles <pid> |
procfiles <pid> |
Solaris plimit is the direct equivalent of both /proc/<pid>/limits and prlimit, and is the first command to reach for on that platform. On AIX the per-process limit is the one that usually bites — the system-wide table is largely dynamic — so start here rather than at -23.
Related Errors / Related Topics
- -23 — Too many open files in system. The host-wide counterpart; the table above separates them, and
/proc/sys/fs/file-nrsettles it in one command. - -9 — Bad file descriptor. Not exhaustion, but it appears in the same investigations and the two are worth distinguishing early.
- -11 and -12 — Thread and memory exhaustion. All three share the systemd-override trap, and a host hitting one is often close to the others.
Used-against-limit for the engine's processes is the single most predictive thing to monitor here. Unlike most errors in this range, -24 approaches visibly for weeks before it arrives.