You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
MSVC does not support long paths inside Docker container #622
Expected behavior
The second compilation from the Dockerfile should work just as fine as the first one.
The behavior should match the host environment, where MSVC does not have any issues working with long paths. Even when long path support has not been enabled system-wide.
Configuration:
Edition: Windows 11 Pro (10.0.22631 Build 22631)
Base Image being used: mcr.microsoft.com/windows/servercore:ltsc2022
Container engine: docker
Container Engine version: Docker version 27.5.1, build 9f9e405
Thank you for creating an Issue. Please note that GitHub is not an official channel for Microsoft support requests. To create an official support request, please open a ticket here. Microsoft and the GitHub Community strive to provide a best effort in answering questions and supporting Issues on GitHub.
Root Cause: The LongPathsEnabled registry setting is not being honoured inside Windows containers. This is a platform-level issue (related: #361). The same setup works correctly on the host OS, confirming this is not an MSVC bug.
Workaround: Directory Junction
Create a short-path junction to bypass the 260-char limit:
RUN cmd /c mklink /J C:\short_include ${ENV:LONG_PATH}
RUN C:\BuildTools\Common7\Tools\Launch-VsDevShell.ps1 -Arch amd64;
cl.exe /std:c++latest /IC:\short_include C:\src\main.cpp
Permanent Fix
We've identified this as a credible bug and have escalated it internally for investigation. We'll update this thread as we make progress.
microsoft-github-policy-service commented on Jun 4, 2026
I investigated the issue you raised. Here is what I found:
Windows containers do honor the LongPathsEnabled setting.
I see the same behavior on a normal Windows machine as in a container: the build fails in both.
cl.exe is not long path aware. Its manifest does not declare longPathAware, so it cannot use long paths even when LongPathsEnabled is 1.
The details are below. Every check uses only standard tools (mt.exe, findstr, cmd, PowerShell), so you can run them yourself.
Summary
cl.exe fails with fatal error C1083: Cannot open include file when the full path to the included file is longer than 260 characters. In your repo the include directory path is 255 characters and the full path to example.hpp is 267 characters.
This happens inside a container and on a normal Windows machine, with LongPathsEnabled set to either 1 or 0.
The reason: cl.exe does not declare long path support (longPathAware) in its application manifest. Windows allows a program to use long paths only when both of these are true (Microsoft docs):
LongPathsEnabled is set to 1, and
the program declares longPathAware in its manifest.
Inside the container, programs that do declare longPathAware (PowerShell and cmd.exe) can open the same long path when the setting is 1, and cannot when it is 0. So the container follows the setting.
Workarounds that work today: a directory junction (tested) or a shorter source path (tested); see Workarounds. Neither needs LongPathsEnabled changed. A subst drive should also work, but I did not test it.
How Windows decides whether a program can use long paths
Turning on LongPathsEnabled is not enough by itself. Each program must also opt in through its manifest. This is documented in Maximum Path Length Limitation (see "Enable long paths in Windows 10, version 1607, and later").
LongPathsEnabled
Program declares longPathAware
Long paths work?
0
No
No
0
Yes
No
1
No
No (this is cl.exe)
1
Yes
Yes (for example PowerShell and cmd.exe)
Each program reads the setting when it starts, so inside a container the container's own setting is what counts. Your Dockerfile sets it correctly.
How to check a program's manifest
A program's manifest is stored inside the .exe file. mt.exe (the Microsoft Manifest Tool) can extract it. mt.exe is part of the Windows SDK, which the Visual Studio Build Tools install with the C++ workload when --includeRecommended is used, as in your Dockerfile. In a Developer Command Prompt it is already on the PATH. Otherwise it is under C:\Program Files (x86)\Windows Kits\10\bin\<SDK version>\x64\mt.exe.
If findstr prints a line containing longPathAware>true, the program opts in. If it prints nothing, the program does not opt in, and LongPathsEnabled has no effect on it.
What I tested
Setup:
Host: Windows 11 22H2 with Docker, Hyper-V isolation (the default on Windows 11).
Compiler: MSVC 19.44.35229 from VS 2022 Build Tools 17.14.41 (what your Dockerfile installed when I ran it).
Manifest tool: mt.exe from Windows SDK 10.0.26100, installed with the Build Tools.
I ran three sets of tests:
Your Dockerfile, with mt.exe checks added, and LongPathsEnabled=1 as in your repo.
A test Dockerfile of my own, based on yours, that separates container behavior from compiler behavior. I ran it twice: once with LongPathsEnabled=1 and once with 0 (the servercore default).
The same Windows 11 machine with no container. I installed the same Build Tools directly on it and ran the same compiles, once with LongPathsEnabled=0 and once with 1.
In your Dockerfile the long include directory is 255 characters, and the full path to example.hpp inside it is 267 characters. My test Dockerfile uses a 280-character directory, so the full path to example.hpp is 292 characters.
Results
1. Your Dockerfile. The long /I build fails with C1083 on example.hpp, exactly as you reported. mt.exe shows that cl.exe has no longPathAware entry.
2. Test Dockerfile (container).
Check
LongPathsEnabled=1
LongPathsEnabled=0
PowerShell reads a file at the long path
Works
Fails
cmd.exe type reads a file at the long path
Works
Fails
cl.exe with a short /I path
Works
Works
cl.exe with /I pointing at a junction (C:\s) to the long folder
Works
Works
cl.exe with the long /I path
C1083
C1083
mt.exe results inside the container, the same in both runs:
Program
Declares longPathAware?
powershell.exe
Yes
cmd.exe
Yes
cl.exe 19.44.35229
No
findstr.exe
No
The programs whose manifest declares longPathAware (PowerShell and cmd.exe) follow the LongPathsEnabled setting. The cl.exe manifest does not declare it, so cl.exe fails either way.
3. Same machine, no container.
Check
LongPathsEnabled=0
LongPathsEnabled=1
cl.exe with a short /I path
Works
Works
cl.exe with the long /I path (your 255-character folder)
C1083
C1083
mt.exe gave the same manifest results as in the container. So cl.exe behaves the same with and without a container.
Other checks. Earlier in the investigation I also ran the test Dockerfile with process isolation on Windows Server 2022, and got the same results. On a newer Windows 11 machine with no container and LongPathsEnabled=1, MSVC 19.51 also failed with C1083 on the long /I path, so newer compilers behave the same way.
How to verify in a container
These are a trimmed version of the steps I added to your Dockerfile, after the LONG_PATH folder is created and before your build steps. They use VsDevCmd.bat, which puts mt.exe on the PATH and sets VCToolsInstallDir.
SHELL ["cmd.exe", "/S", "/V:ON", "/C"]
# Check 1: which programs opt in to long paths?
RUN call C:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=amd64 -host_arch=amd64 -no_logo && `
echo === cmd.exe === && `
mt.exe -nologo -inputresource:"%WINDIR%\System32\cmd.exe";#1 -out:C:\TEMP\cmd.manifest && `
(findstr /i longPathAware C:\TEMP\cmd.manifest || echo no longPathAware entry) && `
echo === cl.exe === && `
mt.exe -nologo -inputresource:"!VCToolsInstallDir!bin\Hostx64\x64\cl.exe";#1 -out:C:\TEMP\cl.manifest && `
(findstr /i longPathAware C:\TEMP\cl.manifest || echo no longPathAware entry)
# Check 2: the container honors LongPathsEnabled.
ADD example.hpp ${LONG_PATH}
RUN type %LONG_PATH%\example.hpp
SHELL ["powershell.exe", "-NoLogo", "-ExecutionPolicy", "Bypass"]
Each RUN line is one cmd command, and cmd fills in %VAR% before any of it runs. /V:ON makes !VCToolsInstallDir! take its value after VsDevCmd.bat has set it. The backtick line continuations need # escape=` at the top of the Dockerfile, which yours already has.
Expected output: Check 1 prints a longPathAware line for cmd.exe and no longPathAware entry for cl.exe. Check 2 prints the contents of example.hpp, because cmd.exe opts in and your Dockerfile sets LongPathsEnabled=1. If you remove the registry update that sets LongPathsEnabled, Check 2 fails. Your long /I build still fails afterwards in both cases.
Workarounds
Each of these keeps the paths that cl.exe sees under 260 characters:
Directory junction (tested, works in containers). A junction is a short folder name that points to the long folder. These two steps replace your long /I build step and use your Dockerfile's PowerShell SHELL:
RUN cmd /c mklink /J C:\inc "\\?\${ENV:LONG_PATH}"
RUN C:\BuildTools\Common7\Tools\Launch-VsDevShell.ps1 -Arch amd64; `
cl.exe /std:c++latest /IC:\inc C:\src\main.cpp
The junction shortens only the include path; for output paths, see item 4.
Shorter source path (tested: the short /I builds above). Use a short WORKDIR or clone location such as C:\s.
subst drive (not tested). subst X: <long folder> makes a drive letter that points to a folder; then use /IX:\. A subst drive lasts only for the current session, so create it in the same RUN step as the build.
Keep output paths short too. Object files, PDBs and build folders (/Fo, /Fd) are also subject to the limit.
Also note that a single folder or file name cannot be longer than 255 characters on NTFS, even with long paths enabled.
Related compiler and linker errors you may see with long paths: C1083, C1081, LNK1104.
Next steps
There is an open issue for MSVC long path support: Developer Community issue 10221576. Its title says 255 characters, but the failure is the 260-character limit that applies to programs without longPathAware. Please upvote it and add your scenario. That is the best place to follow a compiler fix.
Based on these results, I don't see a change needed in Windows containers. If you find a program that declares longPathAware and still cannot use long paths inside a container, please share the details here.
Activity
github-actions commentedon Nov 6, 2025
Thank you for creating an Issue. Please note that GitHub is not an official channel for Microsoft support requests. To create an official support request, please open a ticket here. Microsoft and the GitHub Community strive to provide a best effort in answering questions and supporting Issues on GitHub.
xlazom00 commentedon Dec 3, 2025
Is it woking on normal windows? As I don't think so. MSVC and msbuild has problem with long path and I also reported this issues on MS
jdoubleu commentedon Dec 6, 2025
Yes, it perfectly works fine on a normal Windows host. I've set the registry key at
HKLM\SYSTEM\CurrentControlSet\Control\FileSystemin both cases.sureshbabu-msft commentedon May 4, 2026
Hi jdoubleu (@jdoubleu),
Update on Long Path Support in Windows Containers
Root Cause: The LongPathsEnabled registry setting is not being honoured inside Windows containers. This is a platform-level issue (related: #361). The same setup works correctly on the host OS, confirming this is not an MSVC bug.
Workaround: Directory Junction
Create a short-path junction to bypass the 260-char limit:
RUN cmd /c mklink /J C:\short_include ${ENV:LONG_PATH}
RUN C:\BuildTools\Common7\Tools\Launch-VsDevShell.ps1 -Arch amd64;
cl.exe /std:c++latest /IC:\short_include C:\src\main.cpp
Permanent Fix
We've identified this as a credible bug and have escalated it internally for investigation. We'll update this thread as we make progress.
microsoft-github-policy-service commentedon Jun 4, 2026
This issue has been open for 30 days with no updates.
no assignees, please provide an update or close this issue.
microsoft-github-policy-service commentedon Jul 8, 2026
This issue has been open for 30 days with no updates.
no assignees, please provide an update or close this issue.
microsoft-github-policy-service commentedon Aug 11, 2026
This issue has been open for 30 days with no updates.
no assignees, please provide an update or close this issue.
lemeurherve commentedon Aug 11, 2026
sureshbabu-msft: any progress to share by any chance?
microsoft-github-policy-service commentedon Sep 11, 2026
This issue has been open for 30 days with no updates.
no assignees, please provide an update or close this issue.
ramesh-ramn commentedon Oct 9, 2026
Hi jdoubleu (@jdoubleu), thank you for the clear repro repo.
I investigated the issue you raised. Here is what I found:
LongPathsEnabledsetting.cl.exeis not long path aware. Its manifest does not declarelongPathAware, so it cannot use long paths even whenLongPathsEnabledis 1.The details are below. Every check uses only standard tools (
mt.exe,findstr,cmd, PowerShell), so you can run them yourself.Summary
cl.exefails withfatal error C1083: Cannot open include filewhen the full path to the included file is longer than 260 characters. In your repo the include directory path is 255 characters and the full path toexample.hppis 267 characters.LongPathsEnabledset to either 1 or 0.cl.exedoes not declare long path support (longPathAware) in its application manifest. Windows allows a program to use long paths only when both of these are true (Microsoft docs):LongPathsEnabledis set to 1, andlongPathAwarein its manifest.longPathAware(PowerShell andcmd.exe) can open the same long path when the setting is 1, and cannot when it is 0. So the container follows the setting.LongPathsEnabled. Windows caches the setting in each process, so the process that changed it does not pick it up. The remaining failure in Windows image doesn't support file length longer than 260 characters even after setting LongPathsEnabled to 1 #361 was a single file name over 255 characters. That limit applies to each file or folder name, andLongPathsEnableddoes not change it (File System Functionality Comparison: Limits).cl.exedoesn't advertise long path support. There is an open issue about this: Developer Community issue 10221576.LongPathsEnabledchanged. Asubstdrive should also work, but I did not test it.How Windows decides whether a program can use long paths
Turning on
LongPathsEnabledis not enough by itself. Each program must also opt in through its manifest. This is documented inMaximum Path Length Limitation (see "Enable long paths in Windows 10, version 1607, and later").
LongPathsEnabledlongPathAwarecl.exe)cmd.exe)Each program reads the setting when it starts, so inside a container the container's own setting is what counts. Your Dockerfile sets it correctly.
How to check a program's manifest
A program's manifest is stored inside the
.exefile.mt.exe(the Microsoft Manifest Tool) can extract it.mt.exeis part of the Windows SDK, which the Visual Studio Build Tools install with the C++ workload when--includeRecommendedis used, as in your Dockerfile. In a Developer Command Prompt it is already on thePATH. Otherwise it is underC:\Program Files (x86)\Windows Kits\10\bin\<SDK version>\x64\mt.exe.-inputresourcereads the manifest stored as a resource inside the file (Mt.exe).;#1selects resource ID 1, the manifest Windows uses for an.exe(Using Side-by-Side Assemblies as a Resource).If
findstrprints a line containinglongPathAware>true, the program opts in. If it prints nothing, the program does not opt in, andLongPathsEnabledhas no effect on it.What I tested
Setup:
mcr.microsoft.com/windows/servercore:ltsc2022.mt.exefrom Windows SDK 10.0.26100, installed with the Build Tools.I ran three sets of tests:
mt.exechecks added, andLongPathsEnabled=1as in your repo.LongPathsEnabled=1and once with0(theservercoredefault).LongPathsEnabled=0and once with1.In your Dockerfile the long include directory is 255 characters, and the full path to
example.hppinside it is 267 characters. My test Dockerfile uses a 280-character directory, so the full path toexample.hppis 292 characters.Results
1. Your Dockerfile. The long
/Ibuild fails withC1083onexample.hpp, exactly as you reported.mt.exeshows thatcl.exehas nolongPathAwareentry.2. Test Dockerfile (container).
LongPathsEnabled=1LongPathsEnabled=0cmd.exe typereads a file at the long pathcl.exewith a short/Ipathcl.exewith/Ipointing at a junction (C:\s) to the long foldercl.exewith the long/Ipathmt.exeresults inside the container, the same in both runs:longPathAware?powershell.execmd.execl.exe19.44.35229findstr.exeThe programs whose manifest declares
longPathAware(PowerShell andcmd.exe) follow theLongPathsEnabledsetting. Thecl.exemanifest does not declare it, socl.exefails either way.3. Same machine, no container.
LongPathsEnabled=0LongPathsEnabled=1cl.exewith a short/Ipathcl.exewith the long/Ipath (your 255-character folder)mt.exegave the same manifest results as in the container. Socl.exebehaves the same with and without a container.Other checks. Earlier in the investigation I also ran the test Dockerfile with process isolation on Windows Server 2022, and got the same results. On a newer Windows 11 machine with no container and
LongPathsEnabled=1, MSVC 19.51 also failed withC1083on the long/Ipath, so newer compilers behave the same way.How to verify in a container
These are a trimmed version of the steps I added to your Dockerfile, after the
LONG_PATHfolder is created and before your build steps. They useVsDevCmd.bat, which putsmt.exeon thePATHand setsVCToolsInstallDir.Each
RUNline is one cmd command, and cmd fills in%VAR%before any of it runs./V:ONmakes!VCToolsInstallDir!take its value afterVsDevCmd.bathas set it. The backtick line continuations need# escape=`at the top of the Dockerfile, which yours already has.Expected output: Check 1 prints a
longPathAwareline forcmd.exeandno longPathAware entryforcl.exe. Check 2 prints the contents ofexample.hpp, becausecmd.exeopts in and your Dockerfile setsLongPathsEnabled=1. If you remove the registry update that setsLongPathsEnabled, Check 2 fails. Your long/Ibuild still fails afterwards in both cases.Workarounds
Each of these keeps the paths that
cl.exesees under 260 characters:/Ibuild step and use your Dockerfile's PowerShellSHELL:/Ibuilds above). Use a shortWORKDIRor clone location such asC:\s.substdrive (not tested).subst X: <long folder>makes a drive letter that points to a folder; then use/IX:\. Asubstdrive lasts only for the current session, so create it in the sameRUNstep as the build./Fo,/Fd) are also subject to the limit.Also note that a single folder or file name cannot be longer than 255 characters on NTFS, even with long paths enabled.
Related compiler and linker errors you may see with long paths:
C1083,
C1081,
LNK1104.
Next steps
longPathAware. Please upvote it and add your scenario. That is the best place to follow a compiler fix.longPathAwareand still cannot use long paths inside a container, please share the details here.Thanks again for the detailed report.