Repository navigation
DrvFs without metadata returns EPERM from fchmod() #41519
Description
Activity
Logs are required for review from WSL team
If this a feature request, please reply with '/feature'. If this is a question, reply with '/question'.
Otherwise, please attach logs by following the instructions below, your issue will not be reviewed unless they are added. These logs will help us understand what is going on in your machine.
How to collect WSL logs
Download and execute collect-wsl-logs.ps1 in an administrative powershell prompt:
Invoke-WebRequest -UseBasicParsing "https://raw.githubusercontent.com/microsoft/WSL/master/diagnostics/collect-wsl-logs.ps1" -OutFile collect-wsl-logs.ps1
Set-ExecutionPolicy Bypass -Scope Process -Force
.\collect-wsl-logs.ps1
The script will output the path of the log file once done.
If this is a networking issue, please use .\collect-wsl-logs.ps1 -LogProfile networking instead, following the instructions in Collect WSL logs for networking issues
Once completed please upload the output files to this GitHub issue.
See Collect WSL logs (recommended method).
If you choose to email these logs instead of attaching them to the bug, please send them to [email protected] with the GitHub issue number in the subject, and include a link to your GitHub issue comment in the message body, and reply with '/emailed-logs'.
No logs.etl found in the archive. Make sure that you ran collect-wsl-logs.ps1 as administrator and that the logs.etl file is in the archive.
Diagnostic information
Detected appx version: 2.7.11.0
No logs.etl found in archive.
Error while parsing the logs. See action page for details
Diagnostic information
Detected appx version: 2.7.11.0
Hi James (@Zamiell) . This is likely a mount issue instead of a fs issue. The drvfs mounts in your wsl distro are mounted as 0:0 instead of the supposed 1000:1000.
Could you please help confirm if the distro is a fresh install that has just finished the OOBE process? There is a known issue where the mounts are not updated and keeps the 0:0 gid:uid after OOBE completes.
If that's the case, a wsl --shutdown after OOBE should fix the issue.
microsoft-github-policy-service commented on Sep 11, 2026
This issue has been automatically closed since it has not had any author activity for the past 7 days. If you're still experiencing this issue please re-file it as a new issue.
Thank you!
Windows Version
Microsoft Windows [Version 10.0.26100.9168]
WSL Version
2.7.11.0
Are you using WSL 1 or WSL 2?
Kernel Version
6.18.33.2-2
Distro Version
Ubuntu 26.04.1 LTS
Other Software
No response
Repro Steps
Use a WSL-native source file and a destination directory on a Windows drive mounted through DrvFs without the metadata option.
Confirm the mount configuration:
$ mount | grep ' on /mnt/c '
C:\ on /mnt/c type 9p (...,aname=drvfs;...,rw,...)
The mount options should not contain metadata .
Create a writable source file with mode 0644 :
$ printf 'test\n' > /tmp/copyfile-source
$ chmod 0644 /tmp/copyfile-source
$ stat -c '%a' /tmp/copyfile-source
644
Change to any Windows directory where the current user has write access, then reproduce the failure with Node.js:
$ cd /mnt/c/path/to/a/writable/directory
$ node -e "require('node:fs').copyFileSync('/tmp/copyfile-source', './copyfile-destination')"
node:internal/fs/utils:...
Error: EPERM: operation not permitted, copyfile '/tmp/copyfile-source' -> './copyfile-destination'
The file contents are created successfully despite the reported failure:
$ cat ./copyfile-destination
test
The underlying failure can also be reproduced directly:
$ touch ./chmod-probe
$ stat -c '%a' ./chmod-probe
777
$ chmod 0644 ./chmod-probe
chmod: changing permissions of './chmod-probe': Operation not permitted
This occurs even though the Windows ACL permits the current user to modify the file. Writing the same destination with fs.writeFileSync() succeeds, as does copying it with GNU cp .
Related downstream reports:
• libuv/libuv#5257
• nodejs/node#44261
Expected Behavior
On a DrvFs mount without metadata support, arbitrary Unix modes cannot be represented. However, an unsupported fchmod() request that retains at least one write bit should either succeed as a best-effort operation or otherwise avoid turning an already-successful file copy into a reported failure.
In the example above, the destination file should contain the copied data and Node.js fs.copyFileSync() should return successfully. This would be consistent with filesystems such as CIFS/SMB, where inability to preserve the exact Unix mode does not cause libuv’s completed copy operation to fail.
Requests that remove all write bits may still need distinct handling because DrvFs maps that state to the Windows read-only attribute.
Actual Behavior
DrvFs successfully creates and writes the destination file, but fchmod() returns EPERM when software subsequently attempts to preserve the source mode.
Node.js implements fs.copyFileSync() through libuv. After copying the data, libuv calls fchmod() on the destination. The EPERM result causes libuv and Node.js to report that the entire copy failed, even though the destination file was created with the correct contents.
Libuv already treats this mode-preservation failure as non-fatal on CIFS/SMB. DrvFs is exposed as a 9p filesystem, however, so it does not receive that handling. The libuv maintainers are reluctant to parse WSL-specific procfs mount information to identify DrvFs, making it preferable for DrvFs itself to provide behavior that does not cause completed higher-level operations to report failure.
Diagnostic Logs
No response