Informix Error -38
-38 Socket operation on non-socket.
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, particularly the operation in question and the processes that are involved. 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 38 | Meaning |
|---|---|---|
| Linux (glibc) | ENOSYS |
Function not implemented |
| Solaris, AIX, HP-UX (System V) | EL2NSYNC |
Level 2 not synchronized |
| BSD, macOS/Darwin | ENOTSOCK |
Socket operation on non-socket |
The official text — Socket operation on non-socket — is ENOTSOCK, the BSD value, and it points at networking. On Linux, where most Informix instances now run, errno 38 has nothing to do with sockets at all.
The System V value is a STREAMS-era condition that does not appear in a database context.
So in practice this is ENOSYS on Linux. Confirm before going further:
python3 -c 'import os; print(os.strerror(38))'
perl -e '$! = 38; print "$!\n"'
grep -w 38 /usr/include/asm-generic/errno.h # Linux
grep -w 38 /usr/include/sys/errno.h # Solaris, AIX, HP-UX
What ENOSYS Actually Tells You
The system call does not exist here. The program asked the kernel to do something the kernel has no implementation for — or is not willing to admit to having one for.
This is a different statement from every neighbouring "cannot do that" error:
| Error | Symbol | What it means |
|---|---|---|
| -38 (Linux) | ENOSYS |
The operation does not exist on this kernel |
| -22 | EINVAL |
The operation exists; these arguments are not valid for it |
| -1 | EPERM |
The operation exists and you are not allowed to perform it |
| (95 on Linux) | EOPNOTSUPP |
The operation exists; this object does not support it |
EOPNOTSUPP is the one most often confused with ENOSYS, and the difference matters operationally. EOPNOTSUPP from fallocate() means this filesystem cannot preallocate — move the file. ENOSYS means the kernel has no fallocate at all — a far more fundamental statement about the environment.
There are four ways a modern Linux system produces ENOSYS, and they are not equally likely:
- A sandbox is intercepting the call. Overwhelmingly the common cause now.
- The kernel predates the call — a binary built against newer headers running on an older kernel.
- The kernel was built without the feature, or the subsystem is not available.
- A compat layer is missing — a 32-bit binary on a kernel without the 32-bit syscall table.
What This Means in Informix
Containers and seccomp — start here
A container runtime applies a seccomp filter that decides, per system call, whether the kernel will answer. Blocked calls come back as EPERM or ENOSYS depending on the profile and the call. Sandboxed runtimes that reimplement the kernel interface — gVisor and the like — return ENOSYS for anything they have not implemented.
The database server is more exposed to this than an ordinary application, because it uses system calls that general-purpose profiles are least likely to allow:
- Kernel asynchronous I/O.
io_setup,io_submit,io_getevents— and theirio_uringsuccessors — are exactly the kind of call a restrictive profile drops. Informix uses KAIO on Linux where it is available. - Shared memory and memory locking. Large-page and
mlock-related calls, which relate to how the instance places and pins its shared memory. - Scheduling and affinity calls, where virtual processors are bound to processors.
fallocateand extent-management calls used when creating or extending cooked chunks.
The signature is distinctive: the same Informix version, the same configuration, works on the host and fails in the container — or worked in the container until the platform team tightened the profile. Nothing in the instance changed.
Kernel older than the binary
Less common but simpler to confirm. An engine or a client library built against newer kernel headers can call something an older kernel does not provide. This surfaces on long-lived hosts that have been upgraded in place at the application layer and not at the kernel layer.
A feature the kernel does not have
Asynchronous I/O is the realistic one. Where AIO is unavailable — not configured, not compiled in, or exhausted — the engine cannot use KAIO.
The engine can fall back to performing that I/O through AIO virtual processors instead, and there is a documented way to disable KAIO explicitly. Check your version's documentation for the variable and for how many AIO virtual processors to configure; the correct number depends on the workload and on how many CPU VPs are in use, and guessing it is not a good trade for the I/O path.
A C UDR calling something that is not there
A routine built on a development host with a newer kernel, deployed onto an older one. The call is present at compile time and absent at run time, and the failure appears only when that routine is first exercised.
Common Causes
- A container seccomp profile blocking a system call the engine depends on — asynchronous I/O most of all.
- A sandboxed runtime (gVisor, a Firecracker guest with a reduced surface, some managed platforms) that has not implemented the call.
- A kernel older than the binaries running on it.
- Asynchronous I/O unavailable — not configured, not compiled in, or unreachable from inside the sandbox.
- A 32-bit binary on a kernel without compat support.
- A C UDR or client library built against newer headers than the deployment host provides.
- A platform-team change to the container baseline that nobody associated with the database.
Diagnostic Checks
Confirm the symbol. On the System V platforms errno 38 is something else entirely and none of the following applies:
python3 -c 'import os; print(os.strerror(38))'
Establish whether you are in a container, since that answers most of these:
cat /proc/1/cgroup
ls -la /.dockerenv 2>/dev/null
systemd-detect-virt --container 2>/dev/null
grep -i container /proc/1/environ 2>/dev/null | tr '\0' '\n'
Check whether a seccomp filter is applied to the engine's processes. This is the single most informative command here:
grep -i seccomp /proc/<oninit-pid>/status
Seccomp: 0 # no filter
Seccomp: 1 # strict mode
Seccomp: 2 # filter mode — a profile is deciding what the kernel answers
Seccomp: 2 alongside an ENOSYS is effectively the diagnosis.
Find the call that failed. Nothing else identifies it, and the answer determines the remedy:
strace -f -p <pid> 2>&1 | grep -i ENOSYS
strace -f -c -p <pid> # summary, including error counts
An ENOSYS line names the call directly. Take that name to whoever owns the container profile.
Check asynchronous I/O, which is the subsystem most likely to be involved:
cat /proc/sys/fs/aio-max-nr
cat /proc/sys/fs/aio-nr
grep -i aio /proc/slabinfo 2>/dev/null | head
aio-max-nr at zero, or the files absent, means AIO is unavailable to processes on this host.
Compare the kernel against the binaries:
uname -a
cat /etc/os-release
ldd --version | head -1
file "$INFORMIXDIR/bin/oninit"
Check the engine's own view of its I/O configuration:
grep -nE 'VPCLASS|DIRECT_IO|AUTO_TUNE' "$INFORMIXDIR/etc/$ONCONFIG"
onstat -g iof
tail -300 "$INFORMIXDIR/tmp/online.log"
The message log around startup is where an I/O-path problem is most likely to have been recorded in the engine's own words.
Solutions / Resolution
- Identify the specific system call before doing anything else.
stracenames it. Every remedy below depends on knowing which call it was, and none of them can be chosen without it. - If a seccomp profile is blocking it, that is the fix and it is not a database change. Take the call name to whoever owns the container baseline and have the profile amended. Resist the temptation to run the container unconfined to prove the point and then leave it that way — narrow the profile to the calls actually needed.
- Do not work around it by disabling the feature without understanding the cost. Falling back from kernel AIO to AIO virtual processors is a legitimate configuration, but it changes the I/O path and needs the virtual processors configured to match. It is a deliberate choice, not a shortcut past an error.
- If the kernel is older than the binaries, that is the incompatibility. Either the host needs its kernel updating or the software needs to match the platform. Check the supported-platform matrix for the version you are running rather than assuming a newer kernel is always safe.
- If AIO is unavailable on the host, establish whether that is deliberate.
aio-max-nrat zero is a decision somebody made. - For a UDR, rebuild against the deployment platform, not against a newer development host. A routine that compiles is not a routine that will run.
- Record the working profile. Where a container profile has been amended to let the engine run, that amendment is part of the deployment and belongs in the same place as the rest of the configuration. It will otherwise be lost at the next platform refresh and the error will return looking new.
Examples
Works on the host, fails in the container
$ grep -i seccomp /proc/$(pgrep -f oninit | head -1)/status
Seccomp: 2
Seccomp_filters: 1
$ strace -f -p <pid> 2>&1 | grep ENOSYS | head -3
[pid 1042] io_setup(128, 0x7ffd...) = -1 ENOSYS (Function not implemented)
[pid 1042] io_setup(64, 0x7ffd...) = -1 ENOSYS (Function not implemented)
A seccomp filter is in place and asynchronous I/O setup is being refused. The engine's configuration is identical to the host where it works; what differs is the profile.
The remedy is to allow io_setup, io_submit, io_getevents and io_destroy in the profile. Running the container unconfined would also clear the error, and would give away every other protection the profile provides.
The kernel has no AIO to offer
$ cat /proc/sys/fs/aio-max-nr
0
Nothing to allocate. On a host in this state the engine cannot use KAIO regardless of how it is configured, and the choice is between changing the host and configuring the engine to do that I/O through virtual processors instead.
Either is defensible. Doing neither, and leaving an error repeating in the message log, is not.
ENOSYS against EOPNOTSUPP
fallocate(7, 0, 0, 2147483648) = -1 ENOSYS (Function not implemented)
fallocate(7, 0, 0, 2147483648) = -1 EOPNOTSUPP (Operation not supported)
The first says this kernel has no fallocate. The second says it has one and this filesystem will not do it — move the file to one that will.
Same operation, same apparent symptom, different layer, and only the trace distinguishes them. This is the pair worth keeping straight on this error.
Platform Note
| Platform | errno 38 | Realistic here |
|---|---|---|
| Linux | ENOSYS |
Yes — and increasingly common as deployments containerise |
| Solaris | EL2NSYNC |
No — STREAMS-era |
| AIX | EL2NSYNC |
No |
| HP-UX | EL2NSYNC |
No |
| BSD, Darwin | ENOTSOCK |
Not a platform Informix runs on |
ENOSYS exists on the System V platforms at other numbers, so an unimplemented-call failure there will not arrive as -38.
The container dimension is Linux-only in practice, and it is the reason this code has become more interesting than it used to be. An error that once meant "this kernel is too old" now much more often means "something between the engine and the kernel decided not to pass that call through" — a category that did not exist when the message catalogue was written.
| Task | Linux | Solaris | AIX |
|---|---|---|---|
| Trace the failing call | strace -f |
truss -f, dtrace |
truss -f |
| Sandbox state | /proc/<pid>/status Seccomp |
zones: zonename |
WPAR: lswpar |
| Kernel version | uname -r |
uname -a, pkg info |
oslevel -s |
| Async I/O state | /proc/sys/fs/aio-* |
kstat |
lsattr -El aio0 |
On Solaris and AIX the equivalent restriction comes from zones and WPARs rather than seccomp, and presents differently — usually as a permission error rather than an unimplemented one.
Related Errors / Related Topics
- -1 —
EPERM. The other error a seccomp profile produces, and on many profiles the more common of the two: some blocked calls returnEPERM, someENOSYS, and which you get is a property of the profile rather than of the call. If you are investigating a container and seeing -1, the same checks apply. - -22 —
EINVAL. The call exists and the arguments are wrong. Easy to confuse with an unsupported flag, which is often how an unavailable feature actually presents. - -36 — on Linux,
ENAMETOOLONG; the neighbouring page, and another where the official text describes a platform Informix does not run on.
Where -38 appears on a containerised Linux host, trace the call and take its name to whoever owns the profile. The engine is not misconfigured; something between it and the kernel is answering on the kernel's behalf.