C errno codes: ENOENT, EACCES, EINVAL, ERANGE and what each value means
- tool
- C
- versions
- C99, C11, C17, POSIX.1-2001
- os
- linux, macos, windows
errno is the integer a C library or system call sets to say why it failed, for example ENOENT (2, no such file or directory) after fopen on a missing path. Read it only after a function has signalled failure, and print it with strerror(errno) or perror(). The names below are portable across POSIX systems; the numbers shown are the Linux values.
Common errno codes (Linux)
| Name | Value | Meaning | Typical cause |
|---|---|---|---|
| EPERM | 1 | Operation not permitted | Changing owner or using a privileged call without the right |
| ENOENT | 2 | No such file or directory | Path or one of its components does not exist, or a dangling symlink |
| EINTR | 4 | Interrupted system call | A signal arrived while a call was blocked; retry the call |
| EIO | 5 | Input/output error | Hardware or filesystem failure while reading or writing |
| EBADF | 9 | Bad file descriptor | Descriptor is closed or was never opened |
| EAGAIN | 11 | Resource temporarily unavailable | Non-blocking call has no data yet; may equal EWOULDBLOCK |
| ENOMEM | 12 | Cannot allocate memory | malloc or mmap could not get memory |
| EACCES | 13 | Permission denied | File or directory permissions forbid the access |
| EEXIST | 17 | File exists | Creating a file or directory that is already there |
| ENOTDIR | 20 | Not a directory | A path component is a file where a directory is needed |
| EISDIR | 21 | Is a directory | Opening a directory for writing |
| EINVAL | 22 | Invalid argument | A parameter has a value the call does not accept |
| EMFILE | 24 | Too many open files | The process hit its RLIMIT_NOFILE limit |
| ENOSPC | 28 | No space left on device | Disk or quota full |
| EPIPE | 32 | Broken pipe | Writing to a pipe or socket whose reader has gone |
| EDOM | 33 | Numerical argument out of domain | Math function given an argument outside its domain |
| ERANGE | 34 | Numerical result out of range | Result too large, as with strtol on overflow |
| ECONNREFUSED | 111 | Connection refused | Nothing is listening on the target port |
Only EDOM, EILSEQ and ERANGE come from ISO C itself. The rest are defined by POSIX, so they exist on Linux and macOS but are not guaranteed by a bare C compiler on every platform.
Print the codes on your system
This program prints the number and the message for several names, so you can check the table against your C library.
mkdir -p /tmp/work && cd /tmp/work
cat > errno_table.c <<'EOF'
#include <errno.h>
#include <stdio.h>
#include <string.h>
#define SHOW(e) printf("%-7s %3d %s\n", #e, e, strerror(e))
int main(void) {
SHOW(EPERM); SHOW(ENOENT); SHOW(EACCES); SHOW(EEXIST);
SHOW(EINVAL); SHOW(ENOMEM); SHOW(ERANGE);
return 0;
}
EOF
gcc -Wall -o errno_table errno_table.c && ./errno_tableOutput
EPERM 1 Operation not permitted ENOENT 2 No such file or directory EACCES 13 Permission denied EEXIST 17 File exists EINVAL 22 Invalid argument ENOMEM 12 Cannot allocate memory ERANGE 34 Numerical result out of range
Read errno correctly
- Check the return value first.
fopenreturnsNULL,openreturns -1; only then iserrnomeaningful. - Save it at once. Calls such as
printforfclosecan changeerrno. Writeint saved = errno;right after the failing call. - Clear it before calls that signal errors only through
errno.strtolreturns 0 orLONG_MAXon failure and setsERANGE; seterrno = 0before the call and test it afterwards, as shown in convert a string to int in C. - Do not print it when nothing failed. It can hold a stale value from an earlier call.
strerror, perror and thread safety
perror("open") prints open: followed by the message to standard error. strerror(errno) returns the same text as a string, but the buffer may be shared, so use strerror_r in threaded programs. errno itself is thread-local, so each thread sees its own value.
Choosing a response
EINTRandEAGAINare usually retried, not reported.ENOENT,EACCESandEEXISTare user-facing: show the path andstrerrortext.ENOMEM,EIOandENOSPCusually mean the operation cannot continue; clean up and exit with a non-zero status.EINVALnormally points to a bug in the arguments you passed.
FAQ
Why does errno hold a value after a function succeeded?
Because no function sets errno back to zero. The Linux errno manual says a successful call is even allowed to change it, so the value is meaningful only right after a call that reported failure through its return value. Check the return value first, then read errno.
Are the numeric errno values the same on every system?
No. Only the names are portable. The numbers in the table are the Linux values, and macOS, Windows and other Unix systems use different numbers for some names. Always compare against the macro, such as ENOENT, and print text with strerror() or perror() rather than hard-coding numbers.
Is errno safe to use in a multithreaded program?
Yes. The Linux manual states that errno is thread-local, so setting it in one thread does not change its value in any other thread. Read it in the same thread that made the failing call, and copy it to a local variable before calling anything else that could overwrite it.