Informix Error -58
-58 Can't send after socket shutdown.
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
| Value | Symbol | |
|---|---|---|
| Catalogue text — Can't send after socket shutdown | 58 | ESHUTDOWN on BSD |
ESHUTDOWN on Linux |
108 | Cannot send after transport endpoint shutdown |
| Errno 58 on Linux | 58 | nothing — 58 is unused |
Two things are unusual here.
Errno 58 is one of only two gaps in the Linux table — the other is 41, which has its own page. strerror(58) returns Unknown error 58: glibc has no name for the value.
python3 -c 'import os; print(32, os.strerror(32)); print(58, os.strerror(58)); print(108, os.strerror(108))'
More importantly, Linux reports this condition as a different error entirely. Writing to a socket whose local send side has been shut down returns EPIPE on Linux — errno 32, which is -32 in this catalogue, and where the material lives:
EPIPE— The local end has been shut down on a connection-oriented socket.
So on a Linux host the condition described here does not arrive as -58. It arrives as -32, alongside the far more common broken-pipe cases.
What ESHUTDOWN Actually Tells You
shutdown() was called on the socket — closing its send direction — and something then tried to send on it anyway.
The distinction from its neighbours turns on who ended the connection, and all three are easily conflated:
| Error | Symbol | What happened |
|---|---|---|
| -58 | ESHUTDOWN |
This end shut down its own send side, then wrote |
| -32 | EPIPE |
The peer is gone — and on Linux, also the case above |
| -54 | ECONNRESET |
The peer sent a RST |
| -57 | ENOTCONN |
There is no connection at all |
shutdown() is not close(). It half-closes a connection while leaving the descriptor open, which is a deliberate technique — signal "I have finished sending" and then carry on reading the response. Writing after that is a defect in the sequence, not a network event.
What This Means in Informix
Nothing in the engine's ordinary connection handling produces this, and on Linux it would not carry this number if it did. Where it appears, it points at code around the instance:
- Client code using a half-close pattern —
shutdown(SHUT_WR)to mark the end of a request, then writing again by mistake. - A connection pool that shuts down a socket on return and hands it out again without reopening.
- A wrapper, agent or monitoring probe with its own socket handling.
- Cleanup ordering, where a shutdown path runs while another thread is still sending on the same descriptor.
Where no such code exists in the path, treat the value with the suspicion -33 describes — particularly on Linux, where the number corresponds to nothing the kernel can report.
Common Causes
- A write after
shutdown(SHUT_WR)on the same socket. - A connection pool returning a shut-down socket to service.
- A race between a cleanup path and a sending thread on one descriptor.
- A half-close protocol implemented incorrectly — writing after the end-of-request signal.
Diagnostic Checks
Confirm the symbol first. On Linux this number means nothing at all, so the check is not a formality:
python3 -c 'import os; print(58, os.strerror(58)); print(108, os.strerror(108))'
If the answer is Unknown error 58, the value did not come from this kernel — read -41, which covers that situation in full, and then look at -32, which is where Linux reports this condition.
Trace the sequence. The pattern is unmistakable: a shutdown() followed by a send() on the same descriptor:
strace -f -e trace=shutdown,send,sendto,write,close -p <pid> 2>&1 | grep -iE 'shutdown|ESHUTDOWN|EPIPE'
shutdown(11, SHUT_WR) = 0
sendto(11, "...", 128, 0, NULL, 0) = -1 EPIPE (Broken pipe)
The descriptor number is what links the two lines.
# Solaris / AIX
truss -f -t shutdown,send,write -p <pid>
Check the surrounding errors, since on Linux this condition is reported as -32 and will be mixed in with genuine broken pipes:
grep -oiE 'system error = [0-9]+' "$INFORMIXDIR/tmp/online.log" | sort | uniq -c | sort -rn
tail -300 "$INFORMIXDIR/tmp/online.log"
Identify whether custom socket code is involved at all:
onstat -g ses
onstat -g dll
ps -ef | grep -E 'agent|monitor|pool' | grep -v grep
Solutions / Resolution
- On Linux, read -32. The condition is reported there, and a bare 58 on a Linux host came from somewhere other than the kernel.
- Find the
shutdown()and thesend()that follows it. A trace links them by descriptor, and that pair is the defect. - Fix the pool rather than the socket. A pool that shuts down a connection on return and reissues it must reopen instead. Validating on checkout catches it; not shutting down until close avoids it.
- Review the half-close sequence where one is in use.
shutdown(SHUT_WR)is a commitment to stop sending, and any later write is a bug in the protocol implementation rather than a transient failure. - Look for a threading race where cleanup and sending share a descriptor. This produces an intermittent version of the same error and is the harder of the two to find.
- Do not retry. Once the send side is shut down it cannot be reopened; the socket has to be closed and a new one created.
Platform Note
| Platform | This condition | Errno 58 there means |
|---|---|---|
| Linux | reported as EPIPE, errno 32 — see -32 |
nothing; 58 is unused |
| Solaris, AIX, HP-UX | confirm on the host | confirm on the host |
| BSD, Darwin | errno 58, ESHUTDOWN |
this condition |
Linux does define ESHUTDOWN at 108, but its send() path reports a write after a local shutdown as EPIPE — so the symbol exists while this particular condition surfaces under a different one.
That combination makes -58 the least likely code in the block to be what a Linux reader actually has: the number is unused, and the condition is reported elsewhere.
| Task | Linux | Solaris | AIX |
|---|---|---|---|
| Trace shutdown/send | strace -e shutdown,send |
truss -t shutdown,send |
truss -t shutdown,send |
| Socket state | ss -antp |
netstat -an, pfiles |
netstat -Aan |
Related Errors / Related Topics
- -32 — Broken pipe. Where this condition is reported on Linux, and the page to read. It also covers the far commoner case of the peer having gone.
- -57 — Socket is not connected. The neighbouring state error, and usually a consequence of a connection already lost rather than a deliberate shutdown.
- -56 — Socket is already connected, the third of the connection-state errors in this block.
- -41 — the other gap in the Linux errno table, and the page covering what a number with no meaning implies.
Where -58 appears on Linux, the number is the first thing to question. The condition it names is real, but the kernel reports it as -32.