Informix Error -34
-34 Result too large.
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
Errno 34 is ERANGE on Linux, Solaris, AIX, HP-UX and the BSD-derived systems, and the official text — Result too large — is the wording those platforms themselves use. This is one of the few codes in the range where the number and the sentence agree everywhere.
It is also the last such code. -33 and -34 are where the numbering families still coincide; from -35 onward Linux, System V and BSD diverge and the static text can only be right for one of them.
Confirm on the host that logged the error anyway:
python3 -c 'import os; print(os.strerror(34))'
perl -e '$! = 34; print "$!\n"'
grep -w 34 /usr/include/asm-generic/errno-base.h # Linux
grep -w 34 /usr/include/sys/errno.h # Solaris, AIX, HP-UX
Everything below assumes the check returned ERANGE.
ERANGE Has Two Unrelated Meanings
Establish which one you have before anything else. They have nothing to do with each other and lead in opposite directions:
| Meaning | Set by | What it is telling you |
|---|---|---|
| A. The value will not fit | exp(), pow(), log(), strtol(), strtod(), … |
A number overflowed, underflowed, or has no representable result |
| B. Your buffer will not fit it | getcwd(), getpwnam_r(), getgrnam_r(), gethostbyname_r(), … |
Nothing is wrong with the data. The caller supplied too small a buffer and is expected to retry with a larger one |
Meaning A is what the phrase "result too large" leads everyone to assume. Meaning B is the one more likely to have reached a database server, and it is not really an error at all — it is a documented negotiation protocol that some callers implement and some do not.
A. Numeric overflow and underflow
The math library sets ERANGE when the argument was perfectly legal but the answer cannot be represented:
| Call | Range error when |
|---|---|
exp(x), exp2(x), cosh(x), sinh(x) |
Result overflows — returns HUGE_VAL |
pow(x, y) |
Result overflows or underflows |
log(0), log10(0) |
A pole error — returns -HUGE_VAL |
ldexp, scalbn |
Result outside the representable exponent range |
| Any of the above | Result underflows to zero |
The string-conversion family sets it too, and this is easy to forget because these are not math functions:
long v = strtol(s, &end, 10); /* ERANGE if the value exceeds LONG_MAX */
double d = strtod(s, &end); /* ERANGE on overflow or underflow */
That matters wherever a number arrives as text and something parses it for itself — an environment variable, a field in a load file, a string argument handed to a routine.
The contrast with -33 is precise:
- -33
EDOM— you cannot ask that.sqrt(-1). The function has no defined result for that input. - -34
ERANGE— the answer will not fit.exp(1000). The function is defined; the type is not big enough.
B. The caller's buffer was too small
The reentrant lookup functions take a caller-supplied buffer and return ERANGE when the result does not fit in it. The defined behaviour is to allocate a larger buffer and call again:
getpwnam_r(name, &pwd, buf, buflen, &result); /* ERANGE -> retry bigger */
getgrnam_r(name, &grp, buf, buflen, &result);
getpwuid_r(uid, &pwd, buf, buflen, &result);
getgrgid_r(gid, &grp, buf, buflen, &result);
gethostbyname_r(...);
getcwd(buf, size); /* ERANGE -> path too long */
Code that uses a fixed buffer and treats ERANGE as a failure will work for years and then break the day the environment changes underneath it — without anything in that code having changed.
The recommended starting size is meant to be queried rather than guessed:
long n = sysconf(_SC_GETPW_R_SIZE_MAX); /* often 1024 */
long m = sysconf(_SC_GETGR_R_SIZE_MAX); /* often 1024 — and often far too small */
_SC_GETGR_R_SIZE_MAX is the trap. A group's record includes its full member list, so a directory-backed group with thousands of members needs a buffer orders of magnitude larger than the suggested value, and the suggested value is what most code uses.
What This Means in Informix
A database server does account and group lookups routinely — resolving the instance owner, resolving a connecting user, checking group membership for file and database privileges. Those lookups go through the platform's name-service layer, which on an enterprise host usually means LDAP, Active Directory, NIS or SSSD rather than the local files.
That gives meaning B a plausible route into an Informix error, and it has a recognisable signature: the error appears at connection time, for particular users, on a host where nothing about Informix has changed. What changed was the directory.
The realistic contexts:
- A user who is a member of a very large group. A group with tens of thousands of members — the organisation-wide default group is the usual offender — produces a record far too big for a conventionally sized buffer.
- A user belonging to a very large number of groups, which has the same effect on the supplementary-group path.
- A directory server that has started returning fuller records after a schema change, a group merge, or a migration from local files to LDAP.
- A deep working directory reaching
getcwd()'s limit — rarer, but it costs nothing to check. - Text-to-number conversion in something that does its own parsing — a startup script reading an environment variable, a field in a load file, a string argument into a C UDR. The engine validates its own configuration parameters and reports those more specifically; this is about the paths where nothing validates on your behalf.
- A C UDR doing arithmetic that overflows —
exp()on a large input, apow()that runs past the type, orstrtod()on a value from a text column.
Attributing a specific -34 to a name-service buffer is reasoning from what
ERANGEmeans in those calls, not from an incident record. It is a hypothesis to confirm with a system-call trace, and the trace is cheap — see below. Where it is right, the fix is entirely outside Informix.
Common Causes
- A name-service lookup returning a record too large for the caller's buffer — most often a group with a very large membership, resolved through LDAP, AD, NIS or SSSD.
- A user in an unusually large number of groups.
- A directory change — groups merged, a schema extended, membership expanded, or a move from local files to a directory service — that made records larger without anything on the database host changing.
- A numeric string that overflows on conversion in code doing its own parsing — an environment variable, a field in a load file, a string argument to a routine — exceeding the range of the target type.
- A C UDR whose arithmetic overflows or underflows —
exp(),pow(),ldexp(), or astrtod()on column data. getcwd()against a pathname longer than the buffer provided.- A stale
errno, as on -33.ERANGEreported by an operation that could not have produced it is residue, not evidence.
Diagnostic Checks
Establish when it happens. This separates the two meanings faster than anything else — at connection time points at meaning B, during query execution against a user-defined routine points at meaning A:
tail -300 "$INFORMIXDIR/tmp/online.log"
onstat -m
grep -n -iE 'errno|system error|connect|session|user' "$INFORMIXDIR/tmp/online.log" | tail -40
If it is connection-related, size the account's group data. This is the check that confirms or eliminates the buffer hypothesis:
id -a <user>
id -G <user> | wc -w # number of supplementary groups
getent passwd <user>
getent group <primary-group> | wc -c # size of the record in bytes
Then find the large groups on the host generally:
getent group | awk -F: '{print length($0), $1}' | sort -rn | head -10
A record of tens or hundreds of kilobytes against a suggested buffer size of 1024 is the whole answer.
Check what the platform recommends, which is usually far less than what is needed:
getconf GETPW_R_SIZE_MAX
getconf GETGR_R_SIZE_MAX
Check the name-service configuration, since local files rarely produce this and directory services routinely do:
grep -E '^(passwd|group|hosts):' /etc/nsswitch.conf
sssctl user-checks <user> 2>/dev/null
systemctl status sssd 2>/dev/null
journalctl -u sssd --since '1 day ago' | tail -40
Trace it, if you need certainty. This converts the hypothesis into a fact:
strace -f -e trace=openat,read,socket,connect -p <pid> 2>&1 | grep -iE 'nss|sssd|ldap|group|passwd'
ltrace -e 'getgrnam_r+getpwnam_r+getgrgid_r' -p <pid> 2>&1 | head
# Solaris / AIX
truss -f -p <pid> 2>&1 | grep -iE 'door|nscd|getgr|getpw'
An ERANGE returned from a getgr* or getpw* call is unambiguous once you can see it.
If it is query-related, look for the arithmetic. The checks are the same ones as on -33 — find the user-defined routines and see whether they call into the math library:
SELECT procname, externalname FROM sysprocedures
WHERE externalname IS NOT NULL AND langid <> 1;
onstat -g dll # modules actually loaded into the VPs, with their paths
Take the path from the filename column and check what it references:
nm -D /informix/extend/<module>/<module>.bld | grep -iE ' U (exp|pow|ldexp|strtol|strtod|cosh|sinh)'
If a script or wrapper does its own parsing, look for a value that will not fit its type. Environment variables are the usual place, since nothing validates them:
env | grep -iE 'informix|ifx' | grep -E '=[0-9]{10,}'
Run it in the context that failed — under cron or the systemd unit — rather than in your login shell, since that is usually where an unexpected value comes from.
Solutions / Resolution
- Decide which of the two meanings you have before doing anything else. Connection-time and user-specific points at a buffer; execution-time and routine-specific points at arithmetic. The remedies share nothing.
- If it is group size, fix it in the directory, not on the database host. Reduce the membership of the oversized group, or give the affected accounts a primary group that is not the organisation-wide one. This is the durable fix and it usually improves more than Informix.
- Consider the caching layer.
sssdwithenumeratedisabled and appropriate caching, ornscdwhere it is the platform's convention, changes both the size and the frequency of the records being returned. Tuning it is often quicker than restructuring groups, though it treats the symptom. - Do not work around it by adding the user to fewer groups arbitrarily. Group membership carries authorisation; trimming it to clear an error is a change to who can do what.
- In a C UDR, retry the lookup with a larger buffer.
ERANGEfrom a_rfunction is an instruction, not a failure. Start atsysconf(_SC_GETGR_R_SIZE_MAX), double on eachERANGE, and cap it. Code that treats the firstERANGEas fatal is the actual defect. - In a C UDR doing arithmetic, check for overflow deliberately. Set
errno = 0before the call and test afterwards, or use the floating-point exception flags. Decide what the routine should return for an out-of-range result rather than propagating an operating-system error into SQL. - If a configuration value overflows on conversion, correct the value. A parameter with an implausible number of digits is a typo or a unit confusion, and the conversion error is the first thing to notice it.
- Do not treat a
ERANGEreported by an unrelated operation as real. As on -33, a value that the failing call could not have produced is residue; the actual fault is recorded beside it.
Examples
One user cannot connect; everyone else can
Connections from one account fail while the instance is otherwise healthy, and nothing on the database host has been changed.
$ id -G appuser | wc -w
412
$ getent group | awk -F: '{print length($0), $1}' | sort -rn | head -3
2283904 domain_users
18422 developers
9310 dba
The organisation-wide group's record is over two megabytes. The suggested buffer size for a group lookup on this host:
$ getconf GETGR_R_SIZE_MAX
1024
Two thousand times too small. Any code that takes the suggested size and treats ERANGE as fatal will fail for every member of that group, and for nobody else — which is exactly the pattern reported.
The fix is in the directory: this account does not need the organisation-wide group as its primary, and nothing on the database host should be changed to accommodate it.
The suggested buffer is a starting point, not an answer
/* wrong: one attempt, ERANGE treated as failure */
char buf[1024];
if (getgrnam_r(name, &grp, buf, sizeof buf, &res) != 0)
return -1; /* fails on any large group */
/* right: ERANGE means retry */
size_t len = sysconf(_SC_GETGR_R_SIZE_MAX);
if (len <= 0) len = 4096;
for (;;) {
char *b = malloc(len);
if (!b) return -1;
int rc = getgrnam_r(name, &grp, b, len, &res);
if (rc == ERANGE && len < (1U << 24)) { /* cap it */
free(b); len *= 2; continue;
}
/* rc == 0 and res == NULL means "no such group", not an error */
...
}
The cap matters. A retry loop with no ceiling turns a directory misconfiguration into unbounded memory growth inside a virtual processor.
A configuration value that will not fit
This one is illustrative.
SHMVIRTSIZEis used here because it is the parameter everyone recognises, not because an oversized value reports -34 — the engine validates that parameter and will tell you about it more specifically. The shape of the problem is what transfers, not the error number.
$ grep -n SHMVIRTSIZE "$INFORMIXDIR/etc/$ONCONFIG"
SHMVIRTSIZE 32000000000
A number with an implausible count of digits is nearly always a unit error — a value meant as kilobytes entered as bytes is the usual shape.
The general point stands wherever a number arrives as text that something else parses: an environment variable read by a startup script, a field in a load file, a value passed into a C UDR as a string. In those paths nothing validates the parameter on your behalf, strtol() or strtod() is the first thing to notice, and what it reports is ERANGE — a number, with no mention of which value it was reading.
That is the reason to check the intended units directly rather than working back from the error.
Platform Note
Errno 34 is ERANGE on Linux, Solaris, AIX, HP-UX and the BSD-derived systems, and it is the last code in this range where that kind of statement holds.
The lookups behind meaning B are where the platforms genuinely differ — not in the errno, but in the machinery that produces it:
| Task | Linux | Solaris | AIX |
|---|---|---|---|
| Name-service config | /etc/nsswitch.conf, sssd.conf |
/etc/nsswitch.conf, ldapclient |
/etc/methods.cfg, /etc/security/user |
| Inspect a lookup | getent, sssctl |
getent, ldaplist |
lsuser, lsgroup |
| Trace the call | strace, ltrace |
truss, dtrace |
truss |
| Cache layer | sssd, nscd |
nscd |
secldapclntd |
On AIX, lsgroup -a users <group> gives the membership directly and is the quickest way to size a group. On Solaris, ldaplist -l group <name> does the equivalent against the directory rather than the cache, which matters when the cache is the thing that is stale.
The suggested buffer sizes are advisory on every platform and undersized on all of them in a directory-backed environment. Treat sysconf as a floor, never a ceiling.
Related Errors / Related Topics
- -33 —
EDOM. The sibling condition and the one this is most often confused with. -33 is you cannot ask that; -34 is the answer will not fit. Informix's text for -33, Argument too large, reads more like a range error than a domain error, which does not help. - -22 —
EINVAL, Invalid argument. Where the value is not merely too big but not acceptable at all. If you are not sure which you have, -22 is the more common of the two by a wide margin. - -7 —
E2BIG, Argument list too long. The other "too big to fit" error, and one that is about the size of an exec argument list rather than a numeric result. Worth ruling out when the failing operation was launching an external program.
Where -34 appears at connection time and affects some accounts and not others, stop looking at Informix. The pattern is characteristic of a name-service record that has outgrown the buffer someone chose for it, and the investigation belongs with whoever owns the directory.