Informix Error -40
-40 Message too long.
An operating-system error code with the meaning shown was unexpectedly returned to the database server. If the error recurs, note all circumstances and contact IBM Informix Technical Support.
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.
Important platform note. Error codes in this range represent operating-system
errnovalues whose meanings vary between Unix platforms and versions. Confirm the nativeerrnodefinition on the server where the Informix error occurred before diagnosing the problem from the number alone.
Determine the Native Error Meaning
| Platform family | errno 40 | Meaning |
|---|---|---|
| Linux (glibc) | ELOOP |
Too many levels of symbolic links |
| Solaris, AIX, HP-UX (System V) | EL3RST |
Level 3 reset |
| BSD, macOS/Darwin | EMSGSIZE |
Message too long |
The official text — Message too long — is EMSGSIZE, the BSD value, and describes a socket write that exceeded the message size. On Linux errno 40 is about symbolic links, which is a completely different investigation.
python3 -c 'import os; print(os.strerror(40))'
grep -w 40 /usr/include/asm-generic/errno.h # Linux
grep -w 40 /usr/include/sys/errno.h # Solaris, AIX, HP-UX
Everything below concerns ELOOP.
What ELOOP Actually Tells You
Path resolution gave up. While resolving one pathname the kernel followed more symbolic links than it is willing to follow — typically 40 on Linux — and stopped.
Two quite different situations produce that, and only one of them is the obvious one:
- A genuine loop.
apoints tob,bpoints back toa. Resolution would never terminate, so the kernel cuts it off. - A chain that is merely too long. No loop at all — just more links than the limit, accumulated over years by people who each added one.
The second is much more common on a long-lived database server, because every link in the chain looks reasonable on its own.
The counting is per-resolution, not per-link
This explains why a path with two or three visible symlinks can exhaust a limit of 40.
The limit applies to the total number of symlinks traversed while resolving a single pathname, and that includes links encountered in directory components, not just at the end. Resolving:
/informix/chunks/datadbs1
may follow a symlink at /informix, another at /informix/chunks, another at the leaf, and then further links in whatever each of those resolved to. The counts multiply through the path rather than adding up along it.
It is not always a loop — O_NOFOLLOW
A second route to ELOOP involves neither a loop nor a long chain:
open() with O_NOFOLLOW returns ELOOP when the final component is a symlink — any symlink, even a single one pointing straight at a real file.
Security-conscious code uses O_NOFOLLOW deliberately, to refuse to be redirected through a link it did not expect. So a backup tool, a monitoring agent or a hardened script may report ELOOP against a perfectly healthy chunk path whose only crime is being a symlink.
That matters here more than it might elsewhere, because symlinking chunk paths to stable device identifiers is exactly what good practice recommends — see -2, where a chunk symlink to /dev/sdc1 breaking after a reboot is the classic failure. The two pieces of advice collide, and ELOOP from a tool that opens with O_NOFOLLOW is where they collide.
The three ways a symlink breaks a path
Worth keeping separate, because they are diagnosed differently:
| Symptom | errno on Linux | What is wrong |
|---|---|---|
| The link's target does not exist | ENOENT (2) |
Dangling link — see -2 |
| Resolution exceeded the path length limit | ENAMETOOLONG (36) |
Expansion made the path too long |
| Too many links traversed | ELOOP (40) |
A loop, a long chain, or O_NOFOLLOW |
Note the naming coincidence: -31 is EMLINK, "Too many links", which is about hard links and has nothing to do with this. The two are confused on the strength of the words alone.
What This Means in Informix
Symbolic links are ordinary in an Informix installation, and two places accumulate them:
Chunk paths. Pointing a chunk at /dev/disk/by-id/... through a symlink is the recommended pattern, because kernel-assigned /dev/sdX names are not stable across reboots. But storage layers add their own indirection — device-mapper, multipath and LVM each present symlinked names — so a chunk path can resolve through several links before reaching a device node, without anyone having done anything wrong.
$INFORMIXDIR itself. The version-switching pattern — /opt/informix pointing at /opt/informix-14.10.FCx — is widespread and sensible. Where a site has layered it (/opt/informix → /opt/ifx/current → /opt/ifx/14.10.FC9), every path built from $INFORMIXDIR inherits those links, and there are a great many such paths: the message log, sqlhosts, the onconfig, every utility, every shared object.
Add the two together and a single resolution can traverse considerably more links than either part suggests.
Other contexts:
- A backup or staging area reached through symlinked mount points
DBSPACETEMPorDUMPDIRpointing through an indirection someone added- A migration where old paths were preserved as symlinks to new ones, and then the new ones were later symlinked again
- Container images where a path is symlinked into a mounted volume that is itself a symlink on the host
- A genuine loop created by a repointing that was done in the wrong order
Common Causes
- An accumulated chain of symlinks, each added at a different time for a good reason.
$INFORMIXDIRresolving through more than one link, multiplied across every path derived from it.- Storage-layer indirection — multipath, device-mapper or LVM names adding links beneath a chunk symlink.
- A tool opening with
O_NOFOLLOWand reportingELOOPfor a single, healthy symlink. - A genuine loop, usually created while repointing links in the wrong order.
- Migration archaeology — old locations preserved as links to new ones, repeatedly.
- A symlinked directory component deep in a path, where nobody thought to look because the leaf is a real file.
Diagnostic Checks
Confirm the symbol, since errno 40 means something else on the System V platforms:
python3 -c 'import os; print(os.strerror(40))'
Then use namei, which is the whole diagnosis. It walks every component and shows each link and what it resolves to, and it says plainly when it gives up:
namei -l /informix/chunks/datadbs1
namei -l "$INFORMIXDIR/etc/$ONCONFIG"
A loop or an exhausted chain is reported in the output rather than inferred.
Compare one level against full resolution, which tells you how much indirection is present:
readlink /path/to/object # one level
readlink -f /path/to/object # all the way through
stat -c '%N' /path/to/object
Count the chain. Where namei is unavailable or the output is long:
p=/informix/chunks/datadbs1
n=0
while [ -L "$p" ]; do
t=$(readlink "$p")
case "$t" in /*) p="$t" ;; *) p="$(dirname "$p")/$t" ;; esac
n=$((n+1))
printf '%2d -> %s\n' "$n" "$p"
[ "$n" -gt 45 ] && { echo "LOOP or excessive chain"; break; }
done
Check $INFORMIXDIR specifically, since everything else inherits it:
namei -l "$INFORMIXDIR"
readlink -f "$INFORMIXDIR"
Check every chunk path at once:
onstat -d | awk '/^[0-9]/ {print $NF}' | while read -r p; do
printf '%-45s -> %s\n' "$p" "$(readlink -f "$p" 2>&1)"
done
Find the limit this host applies:
getconf SYMLOOP_MAX /
If you suspect O_NOFOLLOW rather than a chain, the trace settles it in one line — an ELOOP against a path with only one link, from a call carrying that flag:
strace -f -e trace=openat,open -p <pid> 2>&1 | grep -iE 'NOFOLLOW|ELOOP'
Solutions / Resolution
- Run
namei -lon the failing path first. It names the problem directly and distinguishes a loop from a long chain without any guessing. - Fix a genuine loop immediately — it is a mistake, not a configuration choice, and nothing resolving through it works.
- Flatten the chain rather than raising anything. The limit is not the problem; seven links where one would do is the problem. Repoint the path at its final stable target and delete the intermediate hops.
- Keep the indirection that earns its place. One symlink from a chunk path to a stable device identifier is deliberate and correct — do not read this error as an argument against it. What to remove is the accumulated chain, not the single hop.
- Give
$INFORMIXDIRat most one level. Because every derived path inherits it, this is the highest-value place to flatten and the easiest to overlook. Changing it is a restart-level change, so plan it rather than doing it live. - If it is
O_NOFOLLOW, the fix is in the tool, not the path. Either configure the tool to accept symlinks, or give it a path that is not one. Do not remove a chunk symlink that exists for device-naming stability to satisfy a backup agent — you will trade this error for the one on -2 at the next reboot. - Record the storage indirection. Where multipath or device-mapper contributes links beneath a chunk path, that is a fact about the estate worth writing down, because the next person to flatten a chain needs to know which hops are theirs to remove and which belong to the storage layer.
Examples
The chain nobody built on purpose
$ namei -l /informix/chunks/datadbs1
f: /informix/chunks/datadbs1
drwxr-xr-x root root /
lrwxrwxrwx root root informix -> /opt/ifx/data
drwxr-xr-x ifxprod ifxprod /
drwxr-xr-x ifxprod ifxprod opt
lrwxrwxrwx ifxprod ifxprod ifx -> /srv/ifx
...
lrwxrwxrwx ifxprod ifxprod chunks -> /srv/ifx/storage/chunks
lrwxrwxrwx ifxprod ifxprod datadbs1 -> /dev/mapper/vg_ifx-lv_data
lrwxrwxrwx root root vg_ifx-lv_data -> ../dm-3
brw-rw---- ifxprod ifxprod dm-3
Nothing here is wrong. A relocation put /informix somewhere else, a later one moved /opt/ifx, the chunks directory was pointed at a dedicated filesystem, and device-mapper supplies the last two hops itself.
Each decision was reasonable and the total is a path resolving through six links — before counting anything contributed by paths derived from it. The fix is to repoint the chunk symlink directly at /dev/mapper/vg_ifx-lv_data and remove the hops that only exist because of where things used to be.
One symlink, and a tool that will not follow it
$ ls -l /informix/chunks/datadbs2
lrwxrwxrwx 1 ifxprod ifxprod 34 Mar 14 09:02 /informix/chunks/datadbs2 -> /dev/disk/by-id/scsi-360014...
$ namei -l /informix/chunks/datadbs2 | tail -2
lrwxrwxrwx ifxprod ifxprod datadbs2 -> /dev/disk/by-id/scsi-360014...
brw-rw---- ifxprod ifxprod scsi-360014...
One link, resolving cleanly to a block device. There is no loop and no chain — and a tool reporting ELOOP against this path is using O_NOFOLLOW and refusing the link on principle.
This symlink is doing exactly what it should: naming the device by a stable identifier instead of by a /dev/sdX name that will move at the next reboot. Removing it to satisfy the tool converts a working configuration into a -2 waiting to happen.
Platform Note
| Platform | errno 40 | Realistic here |
|---|---|---|
| Linux | ELOOP |
Yes — symlink chains around chunks and $INFORMIXDIR |
| Solaris | EL3RST |
No — STREAMS-era |
| AIX | EL3RST |
No |
| HP-UX | EL3RST |
No |
| BSD, Darwin | EMSGSIZE |
Not a platform Informix runs on |
ELOOP exists on the System V platforms at other numbers, so a symlink-resolution failure there will not arrive as -40.
namei is util-linux and has no direct equivalent elsewhere. On Solaris and AIX, walk the path with ls -l per component or trace the failing open():
| Task | Linux | Solaris | AIX |
|---|---|---|---|
| Walk a path | namei -l |
ls -l per component |
ls -l per component |
| Full resolution | readlink -f |
readlink -f |
readlink -f |
| Trace the failure | strace -e trace=file |
truss -t open |
truss -t open |
| Resolution limit | getconf SYMLOOP_MAX / |
getconf SYMLOOP_MAX / |
getconf SYMLOOP_MAX / |
The limits themselves differ, and the POSIX minimum is only 8 — so a chain that resolves on Linux may not on another platform. Check before a migration; deep symlink structures are rarely inventoried until they stop working.
Related Errors / Related Topics
- -31 —
EMLINK, Too many links. The naming collision. That error is about hard links to one inode and has no relationship to this one beyond the words. - -2 — No such file or directory, the error a dangling symlink produces. The most common symlink fault by a wide margin, and the one you will create if you remove a chunk symlink that existed for device-naming stability.
- -36 — on Linux,
ENAMETOOLONG. Symlink expansion lengthens the resolved path, so a deep chain can produce that error instead of this one. The limit applies to the path after resolution.
Where -40 appears on Linux, namei -l on the failing path is the first command and usually the last. The useful outcome is rarely the fix itself — it is noticing how much accumulated indirection the estate is carrying, which nobody has looked at since each hop was added.