Informix Error -49
-49 Can't assign requested address.
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 assign requested address | 49 | EADDRNOTAVAIL on BSD |
| The same condition on Linux | 99 | EADDRNOTAVAIL |
| Errno 49 on Linux | 49 | EUNATCH — Protocol driver not attached, STREAMS-era |
Codes -42 to -55 are the BSD socket block and each sits 50 higher on Linux.
python3 -c 'import os; print(49, os.strerror(49)); print(99, os.strerror(99))'
What EADDRNOTAVAIL Actually Tells You
The address is not one this host can use. Either no interface carries it, or the specific address-and-port combination cannot be assigned.
The distinction from its neighbour is exact and worth holding:
- -48
EADDRINUSE— the address exists here, and something else has it. - -49
EADDRNOTAVAIL— the address does not exist here at all.
One is a contention problem, the other a configuration or timing problem. They are adjacent in the catalogue and adjacent in practice, and the remedies have nothing in common.
There is a second, less obvious source: ephemeral port exhaustion. A host making very many outbound connections to the same destination can run out of usable local port numbers for that tuple, and the connect() fails with this error rather than with anything that mentions ports.
What This Means in Informix
The engine binds a listening socket for each network entry in sqlhosts. If an entry names a specific address rather than a wildcard, that address must be present on an interface at the moment the bind happens.
The timing is the trap. A virtual address that will be present a few seconds later is not present now, and startup ordering is where this error lives:
- A cluster or HA virtual address that has not been brought up yet, or has failed over to the other node. The instance starts, the bind fails, and the address appears shortly afterwards — leaving an instance running with no listener and no obvious reason.
- An instance started at boot before the network is fully configured. A systemd unit without the right ordering, or an init script that runs early.
- A
sqlhostsentry naming an address that belongs to a different host, carried across in a copied configuration. - A container where the address exists on the host and not in the container's namespace.
- An IPv6 address on a host where IPv6 is disabled, or the reverse — see -47 for the address-family side of that.
- A hostname resolving to an address the host does not hold, which is the same fault arriving through DNS rather than through configuration.
On the outbound side — the engine connecting to a replication partner, or a client library connecting out — ephemeral exhaustion is the other possibility, and it looks nothing like a configuration error.
Common Causes
- A virtual or floating address not yet up when the instance started.
- Startup ordering — the instance launched before networking was ready.
- A
sqlhostsentry naming an address this host does not have, often from a copied configuration. - A failover that moved the address to another node while the instance kept running.
- A hostname resolving to the wrong address.
- A container or namespace that does not carry the address.
- Ephemeral port exhaustion on a host making very many outbound connections to one destination.
Diagnostic Checks
Ask whether the host actually has the address. This is the whole question for the inbound case:
ip -br addr
ip addr show | grep -w <address>
hostname -I
Then read what sqlhosts asked for, and resolve it the way the engine would:
cat "${INFORMIXSQLHOSTS:-$INFORMIXDIR/etc/sqlhosts}"
getent hosts <hostname-from-sqlhosts>
getent ahostsv4 <hostname-from-sqlhosts>
getent ahostsv6 <hostname-from-sqlhosts>
A name resolving to an address absent from ip addr is the answer, and getent rather than ping is the right tool because it uses the same resolution path the engine does.
Check whether the address is a cluster resource that may not have been present at the time:
ip -br addr | grep -v ' UP '
crm_mon -1 2>/dev/null
pcs status 2>/dev/null
Check startup ordering where the failure only happens at boot:
systemctl show <informix-unit> -p After -p Wants -p Requires 2>/dev/null
systemctl list-dependencies <informix-unit> 2>/dev/null | head -20
journalctl -u <informix-unit> -b | head -40
An instance ordered before network-online.target will reproduce this on every reboot and never when started by hand — which is the signature people find hardest to place.
Confirm whether a non-local bind is permitted, since that is how HA configurations usually solve the timing problem:
sysctl net.ipv4.ip_nonlocal_bind
sysctl net.ipv6.ip_nonlocal_bind
For the outbound case, check ephemeral availability:
sysctl net.ipv4.ip_local_port_range
ss -s
ss -ant | awk '{print $1}' | sort | uniq -c | sort -rn | head
sysctl net.ipv4.tcp_tw_reuse
A very large TIME-WAIT count against a narrow port range, all to one destination, is ephemeral exhaustion rather than a configuration fault.
And the engine's own record:
tail -300 "$INFORMIXDIR/tmp/online.log"
onstat -g ntt
Solutions / Resolution
- Establish whether the address exists on this host.
ip -br addragainst thesqlhostsentry answers the inbound case outright, and separates it from -48 where the address is present but taken. - If it is a startup-ordering problem, fix the ordering. Make the unit depend on the network being genuinely up rather than merely configured. An instance that starts correctly by hand and fails at every boot is this, and re-running the start by hand hides it rather than fixing it.
- For a floating address, decide deliberately between waiting and non-local bind. Either the instance starts after the address is brought up, or the host is configured to permit binding an address it does not yet hold. The second removes the ordering dependency; it also means a bind can succeed on a node that should not have the address, so it belongs with the cluster configuration rather than being set in isolation.
- If the configuration names another host's address, correct it — and check the rest of that file, since a copied
sqlhostsusually carries more than one wrong entry. - Check the listener after startup, not just the instance. The characteristic outcome is an instance that is up and unreachable, which nothing in
onstat -will show you. - For ephemeral exhaustion, widen the range or reduce the churn. Widening
ip_local_port_rangebuys headroom; connection reuse removes the cause. Both are better than the error recurring under load. - Re-test by binding, not by pinging. An address that answers ICMP from elsewhere tells you nothing about whether this host can bind it.
Examples
The instance is up and nobody can connect
$ onstat -
IBM Informix Dynamic Server Version ... -- On-Line -- Up 00:04:11
$ ss -lntp | grep -w 9088
$
$ grep ol_prod "${INFORMIXSQLHOSTS:-$INFORMIXDIR/etc/sqlhosts}"
ol_prod onsoctcp db-vip sqlexec_prod
$ getent hosts db-vip
10.4.1.30 db-vip
$ ip -br addr | grep 10.4.1
eth0 UP 10.4.1.20/24
The instance is online. The virtual address it was told to bind lives on the other node, or has not been brought up yet. Nothing is listening, and every user reports a connection failure while the instance itself looks healthy.
Works by hand, fails at every boot
$ systemctl show informix -p After | tr ' ' '\n' | grep -i network
After=network.target
network.target means the networking service has been started, not that addresses are configured and up. Ordering after network-online.target — and requiring it — removes a failure that only ever appears on reboot.
Platform Note
| Platform | This condition | Errno 49 there means |
|---|---|---|
| Linux | errno 99 | EUNATCH — STREAMS-era, unrelated |
| Solaris, AIX, HP-UX | confirm on the host | confirm on the host |
| BSD, Darwin | errno 49 | this condition |
| Task | Linux | Solaris | AIX |
|---|---|---|---|
| List addresses | ip -br addr |
ipadm show-addr |
netstat -in, lsattr -El en0 |
| Non-local bind | sysctl net.ipv4.ip_nonlocal_bind |
ipadm / IPMP config |
no -o tunables |
| Ephemeral range | sysctl net.ipv4.ip_local_port_range |
ipadm show-prop -p smallest_anon_port tcp |
no -a | grep ephemeral |
Non-local bind in particular is configured quite differently on each platform, and on Solaris and AIX the equivalent usually belongs to the IPMP or cluster layer rather than to a system tunable.
Related Errors / Related Topics
- -48 — Address already in use. The address exists here and something holds it. The adjacent error, and the first thing to distinguish this from.
- -47 — Address family not supported. Where the problem is the kind of address rather than the specific one, which is how an IPv6 entry on an IPv4-only host presents.
- -51 — Network is unreachable, for the outbound side when there is no route to the destination.
An instance that is online with no listener is the outcome this error produces most often. Check the listener separately from the instance after any start, because nothing in the engine's own status reports its absence.