Was your directory a FUSE-based network mount by any chance?
In addition to a file with that name already existing (other answer), this can happen when a FUSE process that once mounted something at this directory crashed (or was killed, e.g. with kill -9
or via the Linux OOM killer).
Check in mount
if the FUSE mount is still listed there. If yes, you should be able to unmount it and fix the situation using fusermount -uz
.
To see what is happening in detail, run strace -fy mkdir -p $directory
, which shows all syscalls involved and their return values.
I consider the error messages emitted in this case a bug in mkdir -p
(in particular the gnulib
library):
When you run it on a dir that had a FUSE process mounted but that process crashed, it says
mkdir: cannot create directory ‘/mymount’: File exists
which is rather highly inaccurate, because the underlying stat()
call returns ENOTCONN (Transport endpoint is not connected)
; but mkdir
propagates up the less-specific error from the previous mkdir()
sycall.
It's extra confusing because the man page says:
-p, --parents
no error if existing, make parent directories as needed
so it shouldn't error if the dir exists, yet ls -l /
shows:
d????????? ? ? ? ? ? files
so according to this (d
), it is a directory, but it isn't according to test -d
.
I believe a better error message (which mkdir -p
should emit in this case) would be:
mkdir: cannot create directory ‘/mymount’: Transport endpoint is not connected