18

I just got burned by the 260 character path limitation in Windows. Why did Microsoft decided to limit paths to 3 characters for drive + 256 characters + 1 character for the terminator? Mac OS of the same vintage has a 31 character filename limit but no path limit since the FSSpec stored volume number, refnum, and 31 character filename (Pascal string as length byte + 31 characters). HFS running on 512k of RAM could support long paths, but Windows 3.1 and 95 cannot. Newer versions of Windows can under some limited circumstances break the 260 character path limit, but they are limited by compatibility to Win32 headers.

  • 6
    Probably because they used fixed sized buffers to store things like the current working directory and 256 is a nice round number in binary. – Ross Ridge Dec 10 '18 at 18:03
  • 3
    Maximum path size actually supported by NTFS is much bigger (32,000 characters according to the first answer of this question.) 260 character limit is imposed by Windows API any can be easily by-passed with 3rd party software like Total Commander. – wizofwor Dec 11 '18 at 8:41
  • 1
    The 32K limit only works with Unicode. For non-Unicode, the limit is 260. – cup Dec 11 '18 at 13:00
  • 4
    The 32K limit is available in Unicode only, because Windows (NT-based, not Windows 95-based) is a Unicode (ok, UCS-2) Operating System, with an ANSI (ok, ASCII plus various 8-bits extensions like CP and MBCS) backward-compatibility layer for functionality that existed in Windows 95-based OSes. Long Paths are a Windows NT-only feature, and so to use it you need to step out of the 8-bit character set compatibility layer. – Euro Micelli Dec 11 '18 at 17:41
  • 2
    Amazingly enough, the DOS LFN API (first exposed by Windows 95) theoretically supports paths longer than 260 characters... – Stephen Kitt Dec 11 '18 at 20:52
14

In the Windows world, the MAX_PATH 260-character limit dates back to the introduction of the Win32 APIs; it is for example documented in GetWindowsDirectory. Before that, Windows (at least in version 3) documented a 144-character limit; see for example GetSystemDirectory.

As far as why the path limit is 260 characters, the general answer you’ll find on the Internet is backwards compatibility. OK, that’s often the case in computing in general, and on Windows in particular (which is why many 30-year-old Windows programs can still be made to run on modern Windows, at least on 32-bit systems). The question then becomes, backwards compatibility with what?

The obvious answer would be DOS, and perhaps Win16. But DOS has a maximal path limit of 66 characters, constrained by its CDS (current directory structure) which has room for a 67-byte nul-terminated string to store each drive’s path (including drive letter, if appropriate). DOS-based versions of Windows couldn’t change this, since they had to maintain compatibility with DOS programs — imagine being able to store a file in a deeply-nested directory, only to have it be inaccessible from DOS! So the DOS limit doesn’t explain the 256-character limit in Win32. (I’m ignoring network drives here.)

(Incidentally, you can achieve the latter effect by mounting a FAT drive under Linux: Linux allows much longer paths on FAT than DOS or Windows can handle, so you can create directories which are so deeply nested that DOS can’t handle them properly.)

Digging further reveals something interesting; old Windows headers define, in stdlib.h,

#if defined(__OS2__) || defined(__WIN32__)
#define _MAX_PATH       260
#define _MAX_DRIVE      3
#define _MAX_DIR        256
#define _MAX_FNAME      256
#define _MAX_EXT        256
#else
#define _MAX_PATH       80
#define _MAX_DRIVE      3
#define _MAX_DIR        66
#define _MAX_FNAME      9
#define _MAX_EXT        5
#endif

The 80-byte MAX_PATH makes sense for DOS and Win16, based on the CDS above: that’s just enough room for a 66-byte path, \, 12-byte filename (11 bytes stored on disk and . separator), and a nul terminator.

The interesting part is the other definition: the famous 260-byte limit... defined for Win32, and for OS/2! Reading through the OS/2 APIs doesn’t help much, because they’re all designed to not have documented limits (programs are supposed to call DosQuerySysInfo with QSV_MAX_PATH_LENGTH to find the maximum path length), as are in fact most of the Windows APIs (e.g. GetCurrentDirectory which takes a buffer and allocated length, and indicates the required length if the buffer isn’t big enough). But Inside OS/2, in its description of the file system name space, says

All OS/2 filename and pathname interfaces, such as DosOpen, DosFindNext, and so on, are designed to take name strings of arbitrary length. Applications should use name buffers of at least 256 characters to ensure that a long name is not truncated.

So I get the impression that the 256-character limit is part of OS/2’s legacy, and that when it was chosen, 256 characters was considered sufficient for “name strings of arbitrary length”.

  • What I'd read for rationale early in the life of NT was that, though there was a pathname limit of 64K-1 bytes in the OS itself, it was deemed a requirement that application programmers could continue to allocate fixed-size string buffers, i.e., MAX_PATH needed to exist with some value. The specific value is just "seems reasonable". But that's NT when it became "Windows NT". I don't know whether the same limit applied while it was still "NT OS/2". – another-dave Dec 12 '18 at 13:08
  • I haven't read Windows header files in depth so the OS2 connection is news to me. I'm more familiar with the Unix and MacOS headers/interfaces which did not contain explicit limits on path length. However its worth pointing out that HFS did have a maximum filename length, but the data-structures to store file locations did not use paths at all. – Michael Shopsin Dec 12 '18 at 16:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.