Informix Error -14
-14 Bad address.
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, 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.
Operating-System Meaning
errno 14 is EFAULT — Bad address. A system call was handed a pointer that does not refer to memory the process is allowed to touch.
The kernel validates pointers passed across the system-call boundary. When it finds a bad one it refuses the call and returns EFAULT rather than letting the access happen. That refusal is the good outcome: the same bad pointer dereferenced directly in user space produces a SIGSEGV and takes the process down.
So EFAULT and a segmentation fault are two discovery points for the same class of defect:
| Where the bad pointer was used | Result | |
|---|---|---|
-14 EFAULT |
Passed to a system call | The call fails; the process survives |
SIGSEGV |
Dereferenced directly | The process dies, usually with an AF and a core file |
Which one you get is a matter of where the corrupt pointer happened to be used first, not of how serious the underlying problem is.
This error does not have a configuration fix. Nothing in onconfig, no limit, no kernel tunable will change it. A bad pointer means a defect in code or corrupted memory, and the useful work is collecting evidence rather than adjusting settings. That is why the official text offers no remedy and asks you to contact Support with the circumstances.
What This Means in Informix
By far the most likely origin is custom code, not the engine.
ESQL/C host variables
The usual candidates:
- A pointer host variable used without being allocated
- A host variable whose declared length does not match what the server returns, so the library writes past the buffer
- An indicator variable omitted where NULLs can occur, or declared wrongly
- A buffer freed while a cursor is still open against it
- Structure or
varcharhandling where the declared size and the actual size diverge
These commonly appear after a rebuild, a compiler or library change, or a move between 32-bit and 64-bit, because the same source produces different layouts.
C UDRs
A UDR shares the server's address space, so a bad pointer there is considerably more dangerous than in a client — it can corrupt engine memory rather than just its own.
Memory obtained through the DataBlade API is allocated against a duration, and the engine reclaims it when that duration ends. Two distinct mistakes follow from this, and they are worth separating because the second is much easier to write by accident:
- Using an allocation past its own duration. The routine holds a pointer beyond the point at which the engine has reclaimed it — for example keeping something allocated
PER_ROUTINEacross statements, or caching it in a static. - Addressing a pointer from a previous duration after the duration has been changed. The routine switches the current memory duration (
mi_switch_mem_duration()or equivalent), then dereferences a pointer it obtained before the switch. The allocation's lifetime belongs to the duration in force when it was made, not to the one now current, so the earlier pointer can already have been reclaimed. Code that switches duration in the middle of a routine and then continues to work with variables assigned earlier is the usual shape.
The second case is particularly awkward to diagnose because the pointer was entirely valid when it was assigned, the switch looks unrelated to it, and nothing about the failing line suggests a lifetime problem. Check the duration semantics in the DataBlade API guide for your version before relying on any particular reclamation behaviour.
Elsewhere
- Memory corruption in a long-running process — a buffer overrun that damaged a pointer used later, so the failure appears far from its cause
- Hardware — uncorrectable memory errors, rare but real, and worth ruling out when the fault is unreproducible and moves around
- A mismatched library loaded against code compiled for a different version, where structure offsets no longer agree
Common Causes
- An unallocated or freed pointer passed to a system call by client code.
- A buffer overrun that damaged a pointer used later.
- Host variable declarations that do not match the data in ESQL/C.
- DataBlade API memory used past its duration in a UDR.
- A DataBlade API pointer from a previous duration addressed after the duration was changed — the allocation belongs to the duration in force when it was made, so a switch can leave earlier pointers pointing at reclaimed memory.
- A library or header mismatch after a rebuild or upgrade.
- Failing memory hardware, when the fault is unreproducible and inconsistent.
Diagnostic Checks
Find the call and the pointer. strace gives both, and the pointer value itself is informative — a small integer, 0x0, or an obviously wild value tells you something different from a plausible-looking address:
strace -f -p "$pid" 2>&1 | grep EFAULT
# read(9, 0x0, 4096) = -1 EFAULT -> null pointer
# write(7, 0x7f3c40, 2048) = -1 EFAULT -> freed or out-of-range
# Solaris / AIX
truss -f -p "$pid" 2>&1 | grep EFAULT
Look for an assert failure or core file from around the same time — if the process also died anywhere, that is richer evidence than the EFAULT:
grep -n DUMPDIR "$INFORMIXDIR/etc/$ONCONFIG"
ls -lt "${DUMPDIR:-$INFORMIXDIR/tmp}"/af.* "${DUMPDIR:-$INFORMIXDIR/tmp}"/core* 2>/dev/null | head
tail -200 "$INFORMIXDIR/tmp/online.log"
A SIGSEGV or SIGBUS recorded in an AF is the internal case and is worth more than the -14 itself. (A signal 9 is not — see -12.)
Establish what changed, because this class of fault is usually introduced rather than spontaneous:
ls -lt /path/to/application/bin/ | head
ldd /path/to/binary
rpm -qa --last 2>/dev/null | head -20
For client code, run it under a memory checker. This finds the real defect rather than the place it surfaced:
valgrind --leak-check=full --track-origins=yes /path/to/client_program
If the fault is unreproducible, moves between operations, or affects more than one process, rule out hardware:
edac-util -v 2>/dev/null
grep -iE 'mce|hardware error|edac|correctable' /var/log/messages | tail -20
dmesg -T | grep -iE 'mce|hardware error|ecc'
journalctl -k | grep -iE 'mce|hardware error'
# AIX / Solaris
errpt -a | grep -iE 'memory|ecc' # AIX
fmdump -eV | head -40 # Solaris
For ESQL/C, review the declarations against what the query actually returns:
SELECT c.colname, c.coltype, c.collength
FROM syscolumns c JOIN systables t ON c.tabid = t.tabid
WHERE t.tabname = '<table>'
ORDER BY c.colno;
Solutions / Resolution
- Treat this as a defect, not a condition. There is no tuning step. The goal is to identify the code that produced the bad pointer.
- Capture the evidence while you have it —
strace/trussoutput, the AF and core file, the message log around the timestamp, and the exact build of the binary involved. This error is often intermittent, and a second occurrence may be a long way off. - Reduce to a reproducer if you can. A single statement or a single program run that fails reliably is worth far more than a description.
- Run client programs under
valgrind. Most real causes are found in minutes this way, and the report points at the allocation that went wrong rather than at the call that noticed. - Review host-variable declarations against the actual column types and lengths, particularly after any rebuild, upgrade or bitness change.
- In a UDR, audit memory durations in two directions. Check both that no allocation is used beyond the duration it was given, and that no pointer obtained before a duration switch is still being addressed after it. For the second, trace every variable assigned before the switch and confirm it is either re-obtained under the new duration or not touched again. Both patterns produce valid-then-invalid memory, which is exactly this failure.
- Rebuild against matching headers and libraries where a version mismatch is plausible.
- Rule out hardware if the fault is unreproducible, wanders between unrelated operations, or affects several processes at once.
- If the fault appears to be inside the engine rather than in custom code, that is a product issue — escalate with the AF, the core file and the trace rather than attempting local remedies.
Examples
A null pointer from a client program
$ strace -f -p 5512 2>&1 | grep EFAULT
[pid 5512] read(9, NULL, 4096) = -1 EFAULT (Bad address)
A read into a null buffer. The host variable was declared as a pointer and never allocated; the code path that allocates it is skipped when a prior statement returns no rows. Nothing about Informix or the host is at fault.
The pointer was valid once
$ valgrind ./report_daily 2>&1 | grep -A4 'Invalid read'
Invalid read of size 8
at 0x40118A: fetch_rows (report.c:212)
Address 0x5204040 is 0 bytes inside a block of size 4,096 free'd
at 0x4C30D3B: free
by 0x401160: cleanup_batch (report.c:188)
cleanup_batch() frees the buffer while a cursor is still fetching into it. The EFAULT appeared at the next fetch, which is nowhere near line 188 — which is why reading the failing call rarely finds the cause and a memory checker does.
Unreproducible and moving around
$ dmesg -T | grep -i mce
[Sun Sep 7 02:14:08 2026] mce: [Hardware Error]: Machine check events logged
$ edac-util -v
mc0: csrow1: ch0: 1284 Uncorrected Errors
The fault appeared in unrelated operations on unrelated days and never reproduced. Uncorrected memory errors on one rank. Nothing in the database or the application is wrong, and no amount of code review would have found it.
Platform Note
errno 14 is EFAULT on Linux, AIX, Solaris, HP-UX and the BSD-derived systems — stable, so the number is reliable.
Whether a given bad pointer produces EFAULT or a SIGSEGV is not consistent across platforms or even across calls on the same platform: it depends on where the pointer is validated. Code ported from one Unix to another can therefore change from failing loudly with a core file to failing quietly with an error return, or the reverse. A defect that presented as a crash on the old platform and as -14 on the new one is the same defect.
Memory-checking and hardware tooling differ:
| Task | Linux | Solaris | AIX |
|---|---|---|---|
| Memory checker | valgrind |
libumem, dbx check -access |
valgrind (where available), dbx |
| Hardware errors | edac-util, mcelog, dmesg |
fmdump -eV, fmadm faulty |
errpt -a |
| Core analysis | gdb |
mdb, pstack |
dbx |
Related Errors / Related Topics
- -9 — Bad file descriptor. The other error that indicates an application lifecycle defect rather than an environmental condition; the two often occur in the same code.
- -12 — Cannot allocate memory. Worth reading for the assert-failure and signal guidance, which applies here: a
SIGSEGVin an AF is an internal fault, a signal 9 is not. - -22 — Invalid argument, the other errno that indicates a call was made incorrectly rather than that a resource was unavailable.
A single -14 with no recurrence and no other symptom may not be worth extended investigation. A repeating one is a defect that will eventually present as a crash instead, so it is worth pursuing while it is still returning an error rather than taking a process down.