Informix Error -22
-22 Invalid argument.
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, refer to 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 22 is EINVAL — Invalid argument. A system call was made with an argument the kernel would not accept.
It is the broadest errno in this range. EINVAL does not describe a condition in the world — no missing file, no full disk, no failing device — it says the call itself was wrong. So the only productive first step is to find out which call and which argument, and that means tracing rather than reasoning.
That said, on an Informix server three families account for most occurrences, and all three are configuration rather than code:
- Shared memory — a requested segment size or attach address the kernel rejects
- Direct I/O — buffers, offsets or lengths that are not correctly aligned
- Offsets and sizes — a chunk offset or length the device cannot honour
What This Means in Informix
Shared memory: the -12 confusion
When a shared-memory segment is requested that exceeds the kernel's per-segment maximum, shmget() returns EINVAL, not ENOMEM.
That is counter-intuitive. A request for more memory than allowed reads like a memory problem, so the investigation starts at free, at SHMTOTAL, and at -12 — and finds nothing wrong, because there is nothing wrong with the memory. The argument was out of range.
So:
| Symptom | Error | Meaning |
|---|---|---|
Segment larger than kernel.shmmax |
-22 EINVAL |
The size argument is out of range |
| Not enough memory to satisfy a valid request | -12 ENOMEM |
Genuine memory shortage |
If you are looking at a -22 at startup, compare SHMVIRTSIZE against kernel.shmmax before looking at anything else.
SHMBASE is the second shared-memory case. It sets the address at which the engine attaches its segments, and shmat() rejects an address that is not properly aligned or is not usable in the process's address space. A SHMBASE copied between platforms, or between 32-bit and 64-bit builds, is a classic source — the value that was correct on one is not necessarily valid on the other.
Direct I/O alignment
Where the engine uses direct I/O for cooked chunks (DIRECT_IO), the kernel requires the buffer address, the file offset and the transfer length to be aligned to the device's logical block size. A misalignment is rejected with EINVAL, not with a partial read.
This surfaces when:
DIRECT_IOis enabled on a filesystem that does not support it. Support is not universal —tmpfsdoes not, and NFS depends on the mount and the version.- The device's block size is not what the configuration assumed — 4K-native drives behave differently from 512-byte-emulated ones, and storage migrated between the two changes alignment requirements underneath an unchanged configuration.
- A chunk offset is not a multiple of the block size.
Offsets and sizes
- A chunk offset plus size exceeding the device's capacity
- A negative or wildly out-of-range seek
- A size below the kernel's minimum for the object being created
Elsewhere
- Invalid
ioctlparameters, particularly against tape devices - A flags combination the kernel rejects — often after a code or library change
setrlimitwith a soft limit above the hard limit in a startup wrapper
Common Causes
SHMVIRTSIZE(orSHMADD) larger thankernel.shmmax— reported as -22, mistaken for -12.- An invalid or unusable
SHMBASE, often carried between platforms or bitness. DIRECT_IOenabled where the filesystem does not support it.- Alignment mismatch after a storage change, particularly 512e to 4Kn.
- A chunk offset or size the device cannot satisfy.
- An
ioctlinappropriate for the device, typically tape. - A limit set with soft above hard in a wrapper.
Diagnostic Checks
Trace first. On this error the call and its arguments are the diagnosis, and nothing else gets you there as quickly:
strace -f -p "$pid" 2>&1 | grep EINVAL
strace -f /path/to/command 2>&1 | grep -B2 EINVAL
# shmget(IPC_PRIVATE, 8589934592, ...) = -1 EINVAL -> size out of range
# shmat(163841, 0x44000000, 0) = -1 EINVAL -> bad attach address
# pread64(12, 0x7f.., 8192, 4097) = -1 EINVAL -> misaligned direct I/O
# Solaris / AIX
truss -f -p "$pid" 2>&1 | grep EINVAL
Shared memory — compare the request against the kernel's ceiling:
grep -nE 'SHMVIRTSIZE|SHMADD|EXTSHMADD|SHMBASE|SHMTOTAL' "$INFORMIXDIR/etc/$ONCONFIG"
sysctl kernel.shmmax kernel.shmall kernel.shmmni
ipcs -l
SHMVIRTSIZE is in KB; kernel.shmmax is in bytes. Convert before comparing — that unit difference is itself a common source of the mistake.
# what the engine will ask for, in bytes
awk '/^SHMVIRTSIZE/ {print $2 * 1024}' "$INFORMIXDIR/etc/$ONCONFIG"
cat /proc/sys/kernel/shmmax
For SHMBASE, check it against the page size and the process layout:
getconf PAGESIZE
grep '^SHMBASE' "$INFORMIXDIR/etc/$ONCONFIG"
file "$INFORMIXDIR/bin/oninit" # 32-bit or 64-bit
cat /proc/sys/vm/mmap_min_addr
Direct I/O — establish whether it is enabled, whether the filesystem supports it, and what the block size actually is:
grep -nE 'DIRECT_IO|KAIO' "$INFORMIXDIR/etc/$ONCONFIG"
findmnt -T /informix/chunks -o TARGET,SOURCE,FSTYPE,OPTIONS
blockdev --getss /dev/sdX # logical sector size
blockdev --getpbsz /dev/sdX # physical block size
stat -f -c '%s %n' /informix/chunks
A quick, non-destructive test of whether direct I/O works at all on that filesystem:
dd if=/dev/zero of=/informix/chunks/.diotest bs=4096 count=1 oflag=direct 2>&1
rm -f /informix/chunks/.diotest
An Invalid argument from that dd confirms the filesystem or alignment is the constraint rather than anything in Informix.
Offsets — check the chunk offsets are aligned and within the device:
onstat -d
blockdev --getsize64 /dev/sdX
Solutions / Resolution
- Get the failing call from a trace before changing configuration.
EINVALcovers too much ground to guess at. - If it is
shmget, compareSHMVIRTSIZE(KB → bytes) withkernel.shmmax. Raiseshmmaxto comfortably exceed the largest segment the engine will request, or reduce the segment:
Do not raisesysctl -w kernel.shmmax=<bytes> # persist under /etc/sysctl.d/SHMTOTALor add memory — neither is the constraint. - If it is
shmat, reviewSHMBASE. Do not carry a value between platforms or between 32-bit and 64-bit installations. Where there is no specific reason for the value in use, take the platform's documented default. - If it is direct I/O, either move the chunks to a filesystem that supports it or disable
DIRECT_IO. Confirm with thedd oflag=directtest rather than assuming support. - For alignment after a storage change, check the logical and physical block sizes and ensure chunk offsets are multiples of them. Storage migrated from 512e to 4Kn changes this beneath an unchanged configuration.
- For offsets and sizes, confirm the chunk fits within the device.
- Escalate with the trace if the call and arguments look correct. A genuinely invalid argument from the engine, where the configuration is sound, is a product issue and the
straceoutput is the evidence.
Examples
The startup failure that looks like a memory problem
$ free -g
total used free
Mem: 128 41 78
$ grep SHMVIRTSIZE "$INFORMIXDIR/etc/$ONCONFIG"
SHMVIRTSIZE 8388608
$ awk '/^SHMVIRTSIZE/ {print $2 * 1024}' "$INFORMIXDIR/etc/$ONCONFIG"
8589934592
$ cat /proc/sys/kernel/shmmax
4294967296
$ strace -f oninit -v 2>&1 | grep -m1 shmget
shmget(0x52564801, 8589934592, IPC_CREAT|0660) = -1 EINVAL (Invalid argument)
An 8 GB segment against a 4 GB per-segment limit, on a host with 78 GB free. Every memory check looks healthy because memory is not the problem — the size argument is out of range. Had the host genuinely been short, this would have been -12 instead.
DIRECT_IO on a filesystem that does not support it
$ grep '^DIRECT_IO' "$INFORMIXDIR/etc/$ONCONFIG"
DIRECT_IO 1
$ findmnt -T /informix/chunks -o TARGET,FSTYPE
TARGET FSTYPE
/informix/chunks tmpfs
$ dd if=/dev/zero of=/informix/chunks/.diotest bs=4096 count=1 oflag=direct
dd: failed to open '/informix/chunks/.diotest': Invalid argument
tmpfs does not support O_DIRECT. The dd test reproduces the failure in one command, independently of Informix, which makes it a quick way to settle the question either way.
SHMBASE carried across a rebuild
$ grep '^SHMBASE' "$INFORMIXDIR/etc/$ONCONFIG"
SHMBASE 0x44000000
$ file "$INFORMIXDIR/bin/oninit"
…/bin/oninit: ELF 64-bit LSB executable, x86-64
$ strace -f oninit -v 2>&1 | grep -m1 shmat
shmat(163841, 0x44000000, 0) = -1 EINVAL (Invalid argument)
A 32-bit-era attach address in a 64-bit installation. The value was carried forward with the rest of the configuration during a rebuild and is no longer valid.
Platform Note
errno 22 is EINVAL on Linux, AIX, Solaris, HP-UX and the BSD-derived systems — stable, so the number is reliable. What varies enormously is which arguments are acceptable, and that is where this error lives.
| Area | Linux | Solaris | AIX |
|---|---|---|---|
| Shared-memory max | kernel.shmmax |
project.max-shm-memory |
largely dynamic |
| Attach address rules | page-aligned; mmap_min_addr |
page-aligned | page-aligned |
| Direct I/O | O_DIRECT, fs-dependent |
directio(), forcedirectio |
O_DIRECT, JFS2 mount options |
| Block size query | blockdev --getss/--getpbsz |
prtvtoc, format |
lsattr -El hdiskN |
The SHMBASE point deserves repeating per platform: the valid range and the appropriate default differ, and a value that is correct on one platform is frequently invalid on another. This is one of the parameters that should be reset to the platform default on migration rather than carried across.
On Solaris, direct I/O is requested with directio() or a forcedirectio mount option rather than an open flag, so the Linux test above does not translate — check the mount options instead.
Related Errors / Related Topics
- -12 — Cannot allocate memory. The error people reach for when a shared-memory request fails, and frequently the wrong one: a request exceeding
shmmaxis -22, not -12. Read both together when an instance will not start. - -14 — Bad address. The other errno indicating the call itself was wrong rather than a resource being unavailable; -14 points at code, -22 usually at configuration.
- -28 — No space left on device, worth ruling out where a write fails and alignment is not involved.
- -5 — I/O error, where the arguments are valid and the device is failing.
A -22 at startup is almost always configuration, and almost always one of SHMVIRTSIZE, SHMBASE or DIRECT_IO. A -22 in steady-state operation is more likely alignment, and is worth checking against a recent storage change.