Informix Error -39
-39 Destination address required.
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
| Platform family | errno 39 | Meaning |
|---|---|---|
| Linux (glibc) | ENOTEMPTY |
Directory not empty |
| Solaris, AIX, HP-UX (System V) | EL3HLT |
Level 3 halted |
| BSD, macOS/Darwin | EDESTADDRREQ |
Destination address required |
The official text — Destination address required — is the BSD value and describes a socket operation. On Linux errno 39 is about directories and has nothing to do with networking.
python3 -c 'import os; print(os.strerror(39))'
grep -w 39 /usr/include/asm-generic/errno.h # Linux
grep -w 39 /usr/include/sys/errno.h # Solaris, AIX, HP-UX
Everything below concerns ENOTEMPTY.
What ENOTEMPTY Actually Tells You
rmdir() was called on a directory that still has entries in it, or rename() tried to replace a directory that is not empty.
Most of the time that needs no explanation. The case that does is the directory that looks empty and is not.
First, separate it from the three errors that look identical from a script's point of view:
rmdir fails because |
errno on Linux | The fix is about |
|---|---|---|
| The directory has entries | ENOTEMPTY (39) |
What is in it |
| It is a mount point, or a process's working directory | EBUSY (16) |
What is using it |
| The parent directory is not writable | EACCES (13) |
Permissions |
| The path does not exist | ENOENT (2) |
The path |
A cleanup script that reports every failure the same way will send you to the wrong one of those four.
Why a directory that looks empty is not
Three reasons:
- Dotfiles.
lsdoes not show them.ls -Adoes. This accounts for most of the "but it's empty" reports and takes one command to eliminate. - NFS silly-rename files. When a file on an NFS mount is deleted while another process still holds it open, the client cannot simply remove it — so it renames it to
.nfsfollowed by a hex string, and that entry persists until the last handle closes. Arm -rffollowed byrmdirthen fails withENOTEMPTYagainst a directory whose only remaining entry is invisible to a plainlsand will disappear by itself when whatever is holding the file lets go. - A concurrent writer. Something is still creating files in the directory faster than the cleanup removes them. The directory is genuinely not empty; it is just never empty at the moment anyone looks.
What This Means in Informix
This is not an error the engine's own operation is likely to produce. It arrives from the housekeeping around an instance, which is where directories get removed:
- Backup and archive retention. A rotation job pruning old directories — the most common context by a wide margin, and the one where the NFS case applies, since backup targets are frequently on shared storage.
- Logical-log backup cleanup organised by directory.
- Temporary and staging directories — external-table load and unload areas, a
DBSPACETEMPdirectory tree,$INFORMIXDIR/tmp. DUMPDIRcleanup after assert-failure files have been collected.- A decommissioning script removing an instance's directory tree, where the instance is not as stopped as the script assumed.
A cleanup that fails with ENOTEMPTY because the engine is still writing into the directory has found a scheduling fault, not a filesystem one. A script that responds by retrying harder, or by forcing the removal, will do real damage.
Common Causes
- Dotfiles in the directory, invisible to
ls. - NFS silly-rename entries (
.nfsXXXXXXXX) left by a deleted file that something still has open. - A running process still writing into the directory — including, occasionally, the instance itself.
- A retention job racing its own workload, deleting while something creates.
- A subdirectory the removal did not descend into, usually because the script removes files but not directories.
- A permission problem inside the tree that left some entries behind, so the failure is downstream of an earlier, quieter error.
- A
rename()onto an existing non-empty directory, which is a different operation fromrmdirand fails the same way.
Diagnostic Checks
Confirm the symbol, since on the System V platforms errno 39 is unrelated:
python3 -c 'import os; print(os.strerror(39))'
Look properly. ls is not sufficient and is the reason most of these take longer than they should:
ls -A /path/to/dir # includes dotfiles
find /path/to/dir -mindepth 1 -maxdepth 1 -printf '%y %p\n'
find /path/to/dir -mindepth 1 | head -20
Check for NFS silly-rename entries specifically:
ls -A /path/to/dir | grep '^\.nfs'
findmnt -T /path/to/dir -o TARGET,SOURCE,FSTYPE
If any appear, find what is holding the deleted file — the entry disappears when that handle closes:
lsof +D /path/to/dir 2>/dev/null
fuser -v /path/to/dir/.nfs* 2>&1
Check whether anything is using the directory at all, which also distinguishes this from EBUSY:
lsof +D /path/to/dir 2>/dev/null | head
fuser -vm /path/to/dir 2>&1
findmnt /path/to/dir # is it a mount point?
Check whether the directory is genuinely being written to, if the entries keep changing:
find /path/to/dir -mindepth 1 -newermt '-5 minutes' | head
ls -A /path/to/dir | wc -l; sleep 10; ls -A /path/to/dir | wc -l
Two different counts means you are racing a writer, not fighting a stale entry.
And confirm what the instance is doing, before removing anything near it:
onstat -
tail -100 "$INFORMIXDIR/tmp/online.log"
Solutions / Resolution
- Run
ls -Abefore anything else. It resolves the majority of these in one command, and nothing else on this list is worth doing until it has been ruled out. - If they are
.nfsfiles, do not force the removal. They exist because a process still has the underlying file open. Find the process, let it finish or stop it cleanly, and the entries go on their own. Deleting them out from under a running reader is how a backup or an unload ends up truncated. - If the instance is writing there, stop and reconsider the cleanup. A retention job that cannot remove a directory because the engine is using it has found a scheduling problem, not a filesystem one.
- Fix the script to descend properly. Most of these are a cleanup that removes files and not subdirectories.
find <dir> -mindepth 1 -delete, orrm -rfwhere that is genuinely intended, rather thanrm <dir>/*followed byrmdir. - Do not add a retry loop.
ENOTEMPTYdoes not clear on its own except in the NFS case, and there the wait should be for the process, not for the error. - Look upstream if entries were left behind. A directory that will not empty often means an earlier removal failed quietly — usually on permissions — and this error is the first thing loud enough to notice.
- Where a cleanup runs unattended, have it report what remained. A job that prints the output of
find <dir> -mindepth 1on failure turns this into a five-second diagnosis instead of a site visit.
Examples
The directory that is not empty
$ ls /backups/prod_inst/2026-03-01
$ rmdir /backups/prod_inst/2026-03-01
rmdir: failed to remove '...': Directory not empty
$ ls -A /backups/prod_inst/2026-03-01
.nfs00000000012a4f0300000004
An NFS silly-rename entry. Something still has the deleted file open — very often the process that was reading the backup, or a monitoring agent that opened it and has not let go.
$ lsof 2>/dev/null | grep 12a4f03
gzip 28104 ifxprod 3r REG 0,45 ... /backups/prod_inst/2026-03-01/.nfs00000000012a4f0300000004
The compression step from the previous run has not exited. When it does, the entry disappears and the directory removes cleanly. Forcing it now would truncate the file that process is reading.
The cleanup that only removes files
0 4 * * * rm -f /informix/staging/*/* && rmdir /informix/staging/*
The wildcard removes files one level down and leaves every subdirectory below that. The rmdir then fails on any staging directory with nested structure — which is most of them, once anything started writing per-table subdirectories.
0 4 * * * find /informix/staging -mindepth 1 -mtime +7 -delete
One command, descends properly, and respects an age condition rather than removing whatever happens to be there when it runs.
Platform Note
| Platform | errno 39 | Realistic here |
|---|---|---|
| Linux | ENOTEMPTY |
Yes, from housekeeping around the instance |
| Solaris | EL3HLT |
No — STREAMS-era |
| AIX | EL3HLT |
No |
| HP-UX | EL3HLT |
No |
| BSD, Darwin | EDESTADDRREQ |
Not a platform Informix runs on |
ENOTEMPTY exists on the System V platforms at other numbers, so a non-empty-directory failure there will not present as -39.
The silly-rename behaviour is an NFS client property rather than a platform one, so it appears wherever NFS is mounted — but the .nfs prefix and the hex suffix are what to look for on all of them.
| Task | Linux | Solaris | AIX |
|---|---|---|---|
| Show hidden entries | ls -A, find -mindepth 1 |
same | same |
| What holds a file | lsof, fuser |
fuser, pfiles |
fuser, procfiles |
| Mount point check | findmnt |
df -k <path> |
df <path> |
Related Errors / Related Topics
- -16 —
EBUSY.rmdiron a mount point, or on a directory that is some process's working directory. The directory may be genuinely empty and still refuse to go, and the investigation is about what is using it rather than what is in it. - -13 — Permission denied. Removing a directory needs write permission on its parent, not on the directory itself — a distinction that produces a failure indistinguishable from this one inside a script.
- -2 — No such file or directory, where an earlier step already removed it and the cleanup is running twice.
Where -39 appears from a retention or cleanup job, ls -A is the first command and very often the last. Where it appears near a running instance, treat it as a question about what is still writing there before treating it as a directory to be removed.