David Bakin’s programming blog.


Imposible Filenames on Windows: AUX, NUL, CON, etc.

I’m new to the Conan package manager and discovered, after using it for a day, that it placed its package build cache, by default, somewhere I didn’t want it. (On my C:\ drive, not on the dev drive I was using.) I found out how to move it (via env var or .conanrc) and in preparation ran the command to clean the cache: conan cache clean. Which failed to clean the cache as follows:

C:\Users\david>conan cache clean
Found 18 pkg/version recipes matching * in local cache
ERROR: Couldn't remove folder: C:\Users\david\.conan2\p\b\opens51b067f3c7d0f
Cannot change permissions for C:\Users\david\.conan2\p\b\opens51b067f3c7d0f\b\src\NUL! Exception info: (<class 'OSError'>, OSError(22, 'The parameter is incorrect'), <traceback object at 0x0000024173FBC500>)
Folder might be busy or open. Close any app using it and retry.

So it points to inability to delete a file called NUL, and sure enough, looking in the package cache I see 18 files called NUL, one in each pkg/version directory.

Conan (or possibly the Conan CMake provider, or the Conan CLion plugin) is creating files called NUL: A forbidden filename on Windows filesystems!

Cut to the chase: You can delete this forbidden filename files by using the \.\\ syntax to triggerWin32 device namespace name resolution - use a full path:

DEL "\\.\C:\Temp\NUL"
Example: Deleting forbidden file with Win32 "device namespace" syntax
C:\Temp>mkdir X

C:\Temp>copy con x\com1
jk;jk;j;
^Z
        1 file(s) copied.

C:\Temp>cd X

C:\Temp\X>dir
 Volume in drive C is Windows
 Volume Serial Number is 1E4D-4C7F

 Directory of C:\Temp\X

01/12/2026  05:22 PM    <DIR>          .
01/12/2026  05:22 PM    <DIR>          ..
01/12/2026  05:22 PM                10 com1
               1 File(s)             10 bytes
               2 Dir(s)  1,643,622,805,504 bytes free

C:\Temp\X>del com1
The filename, directory name, or volume label syntax is incorrect.

C:\Temp\X>del "\\.\com1"
The system cannot find the path specified.

C:\Temp\X>del "\\.\C:\Temp\X\com1"

C:\Temp\X>dir
 Volume in drive C is Windows
 Volume Serial Number is 1E4D-4C7F

 Directory of C:\Temp\X

01/12/2026  05:23 PM    <DIR>          .
01/12/2026  05:22 PM    <DIR>          ..
               0 File(s)              0 bytes
               2 Dir(s)  1,643,688,939,520 bytes free

C:\Temp\X>

I have seen this before with other programs! It comes as a surprise to Unix/Linux programmers (and even some Windows programmers I bet) that Windows file systems have, in addition to _individual characters_ that cannot be in a file name (e.g., `<`, `>`, `\`, `/`, `:` and others), also forbidden actual file names. Which are:
  • CON, PRN, AUX, NUL
  • COMx, LPTx where x can be any digit in [123456789¹²³]
    • yes, including the superscript digits for 1, 2, and 3!
  • any of the above with any extension.

This is described in the Windows App Development documentation “Naming Files, Paths, and Namespaces which list other questionable filenames, and which does not tell you that these forbidden names are there because that’s the way it was done in CP/M back in the day, and now the rule is preserved for legacy compatibility and it is too too late to change.

  • (Except that CP/M doesn’t have the superscript digits in its character set. So that restriction must have come (much) later. I wonder what the use case was, or which large important customer complained to Microsoft that COM² was allowed and it shouldn’t have been?)

However! It’s actually more complicated than that. You can in fact create these files rather easily at the command line. E.g., consider the following, which shows you cannot create (or delete) COM1 in the current directory, but you can create it (or delete) in a subdirectory if you name it as X\COM1 (expand the Example section below to see it):

Example: Creating/deleting—or _not_ creating/deleting—forbidden file `com1` via the command prompt
C:\Temp>mkdir X

C:\Temp>copy con com1
jljk;
The system cannot find the file specified.
        0 file(s) copied.

C:\Temp>copy con x\com1
j;jlk
^Z
        1 file(s) copied.

C:\Temp>dir X
 Volume in drive C is Windows
 Volume Serial Number is 1E4D-4C7F

 Directory of C:\Temp\X

01/12/2026  03:02 PM    <DIR>          .
01/12/2026  03:01 PM    <DIR>          ..
01/12/2026  03:02 PM                 7 com1
               1 File(s)              7 bytes
               2 Dir(s)  1,643,719,131,136 bytes free

C:\Temp>type X\com1
j;jlk

C:\Temp>cd X && type com1
The system cannot find the file specified.

C:\Temp\X>del com1
The filename, directory name, or volume label syntax is incorrect.

C:\Temp\X>cd .. && del X\com1

C:\Temp>dir X
 Volume in drive C is Windows
 Volume Serial Number is 1E4D-4C7F

 Directory of C:\Temp\X

01/12/2026  03:02 PM    <DIR>          .
01/12/2026  03:01 PM    <DIR>          ..
               0 File(s)              0 bytes
               2 Dir(s)  1,643,719,094,272 bytes free

C:\Temp>

But Windows APIs may work differently.

In particular, del /s /q ... may fail to delete these forbidden files under the named directory, and so may programs on encountering them. And programs which attempt to delete these files—or directory trees containing these files—may not only fail but also report the failure with incomplete or misleading error messages that don’t immediately point out the problem to you.

Another nasty thing that will bite the Windows developer is trying to clone, in git (or another VCS) a repository which contains files like this: That’ll fail, and then you’re stuck trying to figure out what’s the best way to proceed with some Unix-centric library that you’d like to use and would otherwise be able to use if only you could actually, you know, make a proper copy of it. I’ve seen repos with perfectly reasonable files named aux, aux.txt, and com. (For some reason this seems to more often happen with code bases that use GNU autoconf.)