Skip to content

[WSL2] File changes made by Windows apps on Windows filesystem don't trigger notifications for Linux apps #4739

Open

Description

WSL2 is really close to being a perfect runtime environment for server apps being developed in Windows. Great job! One missing feature however is breaking a core part of the developer flow.

For sources stored on the Windows filesystem, any changes made by Windows applications such as Visual Studio do not trigger any file change notifications as far as Linux apps are concerned. This means that all "live rebuild"-type tools don't work (examples: webpack --watch, jekyll --interactive, and Tilt.dev) when running under WSL2. This unfortunately renders many modern dev workflows unviable.

Notes:

Bug report template

  • Your Windows build number: 10.0.19033.1

  • What you're doing and what's happening:

    This applies to all tools that listen for file change notifications, but as an example take webpack. Repro steps:

    • In your Windows filesystem, create an empty directory (example: c:\repro), and then add these three files to it
    • In a WSL2 Ubuntu 18.04 environment, install Node and NPM: sudo apt-get install nodejs npm
    • Still in WSL2, go into the directory from earlier: cd /mnt/c/repro
    • Restore NPM dependencies: npm i
    • Run Webpack in watch mode: npm run build:watch. Wait a few seconds until it completes the first build. It will now be waiting for further changes to your source files.
    • In a Windows application (e.g., Notepad or Visual Studio), open c:\repro\index.js and save some change to it. For example, change 'Hello, world' to 'Hello, world 2'.
  • What's wrong / what should be happening instead:

    Expected behavior: Webpack should see the change and rebuild. That is, you'll see it log information about another build, and the output in dist/bundle.js will be updated.

    Actual behavior: Webpack doesn't respond at all, because there's no file change notification.

Finally I understand that the fix for this is likely to be "add file watch capabilities to the Plan9 server", and you may feel this is already being tracked by #4064. However #4064 describes a more obscure symptom of this missing feature and makes it sound like an intermittent issue. What I'm reporting here is not intermittent at all, and is a pretty mainstream scenario (using tools like webpack --watch). Thanks!

Activity

  1. therealkenc commented on Dec 6, 2019

    @therealkenc

    Yes, #4064 is most unfortunately titled. Worse, the OP has no repro steps and an unecessary symlink confusing the direction they are talking about. Craig's notepad.exe repro with cat isn't an inotify(7) (file watcher) problem, even if implementing inotify is the fix to whatever loosly implied sync problems are going on over there.

    Nevertheless #4701 got closed as a dupe with (quoth):

    We need to add file watch capabilities to the Plan9 server that serves files to a WSL2 distro, and we're tracking that work item here

    So, best I can tell, #4064 is being treated as the LZ for inotify triggers from Windows to WSL2. For lack. #4169 is pretty much exactly your use-case also landed dupe #4064.

    This did work great on WSL1

    Yes, known regress.

  2. nake89 commented on Jan 4, 2020

    @nake89

    Is there a temporary fix to this? This is giving me a headache.

    Using Windows 10, WSL 2. Running npm run serve on my Vue project, which normally hot reloads when I do changes (on my Linux and Mac, and WSL1 and I think maybe WSL2 before(?)). Now I have to shut down and restart the Vue server.

    Will probably just install Linux on this machine. Developing on a Windows machine is a real pain.

  3. craigloewen-msft commented on Jan 6, 2020

    @craigloewen-msft
    Member

    Kevin Kivi (@nake89) are you able to move your project over to the Linux root file system? i.e: Store in your Linux home folder for example? Are there any factors that are blocking you from doing so?

    And per therealkenc 's comment this would be a much better landing zone for adding inotify to the 9P file server. I'll update my comment in #4701 to point here, and add some tags to this issue.

  4. nake89 commented on Jan 7, 2020

    @nake89

    Craig Loewen (@craigloewen-msft) Thanks for messaging me back! I actually solved my issue by moving my project to the linux filesystem in WSL and have had no problems so far. I suggest doing the same. In VS Code simply type ctrl-shift-p and then type "Remote-WSL: New Window" This lets users use the linux filesystem in vs code, for those that did not know this :)

  5. SteveSandersonMS commented on Jan 7, 2020

    @SteveSandersonMS
    Author

    Kevin Kivi (@nake89) That's great if your scenario allows it. But just to clarify for anyone else reading, that's not a solution in general as it doesn't work for other Windows-based editors such as VS.

  6. craigloewen-msft commented on Jan 7, 2020

    @craigloewen-msft
    Member

    Steve Sanderson (@SteveSandersonMS) agreed, we will still be tracking this issue here. :)

  7. Carl-Hugo commented on Feb 1, 2020

    @Carl-Hugo

    Craig Loewen (@craigloewen-msft) Thanks for messaging me back! I actually solved my issue by moving my project to the linux filesystem in WSL and have had no problems so far. I suggest doing the same. In VS Code simply type ctrl-shift-p and then type "Remote-WSL: New Window" This lets users use the linux filesystem in vs code, for those that did not know this :)

    This is a great workaround that will save me lots of time until WSL2 supports this use-case. Thanks for sharing!

  8. Carl-Hugo commented on Feb 5, 2020

    @Carl-Hugo

    Craig Loewen (@craigloewen-msft) Thanks for messaging me back! I actually solved my issue by moving my project to the linux filesystem in WSL and have had no problems so far. I suggest doing the same. In VS Code simply type ctrl-shift-p and then type "Remote-WSL: New Window" This lets users use the linux filesystem in vs code, for those that did not know this :)

    This is a great workaround that will save me lots of time until WSL2 supports this use-case. Thanks for sharing!

    I wrote a small blog post explaining this workaround and talking about a few more things that I discovered/experienced, using Jekyll on WSL2: Speed up your builds to up to 375% and watch for changes for an even faster dev cycle using this workaround on WSL2/Ubuntu, if that can help someone.

    Note: that applies to more than just Jekyll, Jekyll it was just the catalyst.

  9. safizn commented on Feb 5, 2020

    @safizn

    For those stumbling upon, some notes about WSL2 features & limitations (OS build 19041.21, insiders slow ring):

    • inotify filesystem events are not propagated between WSL2 & Windows. Although it will be supported in future releases as stated in Microsoft documentation.
    • Accessing Windows filesystem from WSL2, when developing is extremely slow. While moving projects to WSL2 filesystem, will increase performance, much faster than WSL1 & Windows development. (WSL2 can be accessed in path \\wsl$\)
    • VSCode installed in Windows, with remote extension pack, will install VSCode server automatically in WSL2. Some extensions should be installed in the WSL2 side to work, when openning files from the local WSL2 filesystem. The VSCode Extenions tab in the UI provides indications and guides through the required changes.
    • localhost is managed for you by Windows, and allows access to WSL2. Some cases require accessing the WSL2 VM by it's IP directly.
    • Symlinks in WSL2 work seamlessly between WSL2, Docker containers, & Windows, which wasn't the case with WSL1. Using Docker Desktop on WSL2 experimental feature.
    • Some graphical programs (e.g. SmartGit/GitKraken) need to be installed in WSL2 and accessed through GUI client through Windows (Unix X server), to overcome the inotify events & performance degredations.
  10. ivellios commented on Mar 9, 2020

    @ivellios

    While I am having similar issue with my React App and I am looking for a solution to this as well, I can reply to:

    I can't easily move my files to the Linux filesystem because I need to use PhpStorm and other Windows tools in my dev environment, and I also have other stuff such as Google drive sync running to back up local changes. So the workaround doesn't work for me.
    @weknowsoftware

    Kevin Kivi (@nake89) That's great if your scenario allows it. But just to clarify for anyone else reading, that's not a solution in general as it doesn't work for other Windows-based editors such as VS.
    Steve Sanderson (@SteveSandersonMS)

    This hint by @myuseringithub:

    • Accessing Windows filesystem from WSL2, when developing is extremely slow. While moving projects to WSL2 filesystem, will increase performance, much faster than WSL1 & Windows development. (WSL2 can be accessed in path \\wsl$\)

    is a great one to help you! Also I found out yesterday that since \\wsl$\ is a network resource in Windows you can easily map it to a drive. Then in ANY editor/tool you can use it as if it was on your computer. Just go to the Explorer and manually enter this address to access the resource. You will most likely see "Ubuntu" folder. It is a root of your WSL and it can be mapped to the drive (right click -> map to drive). That helped me setup my project on WSL natively, while being able to edit in the windows editor.

    Though now I am struggling with Docker containers permissions, which I hope to solve separately and see if reloads in my app work.

    Hope that helps.

  11. nicks commented on Mar 27, 2020

    @nicks

    Is there anything that app devs can do to workaround this in their apps? e.g., is there a different file-change notification API that would work on WSL2 across filesystems? (there are a lot of different file-change notification APIs). Or should we wait patiently for inotify support?

  12. Carl-Hugo commented on Mar 27, 2020

    @Carl-Hugo

    Is there anything that app devs can do to workaround this in their apps? e.g., is there a different file-change notification API that would work on WSL2 across filesystems? (there are a lot of different file-change notification APIs). Or should we wait patiently for inotify support?

    You can use the Linux file system directly, accessible from Windows too; see #4739 (comment)

  13. 159 remaining items

  14. raulcastillabravo commented on May 11, 2025

    @raulcastillabravo

    I also solved it by moving my project to WSL (Windows Subsystem for Linux) and running everything from there. I’m using React with Vite inside a Dev Container, and fast refresh is now working properly.

    It seems the root cause is that inotify events are not shared between the host and the container.

    I wrote an article on LinkedIn explaining the full process to fix it:: https://www.linkedin.com/pulse/desarrollar-en-linux-dev-containers-desde-windows-ra%C3%BAl-castilla-bravo-cjqaf

    Issue still occurs, I fixed it by moving all files to Ubuntu WSL and running VSCode in Ubuntu (not docker) WSL. I used monorepo with nextjs and docker compose

  15. raffaeler commented on May 11, 2025

    @raffaeler

    More simply, I solved by migrating to Ubuntu desktop without Windows at all.
    Pros: much faster file system and better virtualization using KVM which allows me to virtualizing any peripheral (GPU included).

  16. giuinnox commented on Jul 25, 2025

    @giuinnox

    i guess this problem is still there and it will not be fixed...
    time to go back to linux?

  17. kieronlanning commented on Aug 14, 2025

    @kieronlanning

    Is this on a roadmap on the WSL team's board?

  18. jankap commented on Oct 5, 2025

    @jankap

    Is this on a roadmap on the WSL team's board?

    Why should it? The solution is to work in the WSL filesystem, and Microsoft recommends that you do this whenever you open VS Code.

  19. kieronlanning commented on Oct 5, 2025

    @kieronlanning

    Is this on a roadmap on the WSL team's board?

    Why should it? The solution is to work in the WSL filesystem, and Microsoft recommends that you do this whenever you open VS Code.

    Because it's not always practical, and not obvious. It look a lot of effort to find out what the issue was in the first place - weeks of off and on investigation.

    As this effectively silently fails in an un-standard way, yes... I think it requires a solution.

  20. jankap commented on Oct 6, 2025

    @jankap

    I agree it should be made more obvious, i.e., better documented.

    I'm afraid this is a complex problem that lies deep within the filesystem drivers; otherwise, they would have fixed it.

    I wouldn't expect to get it solved, tbh. MS seems not to be focusing on WSL, devcontainer, remote development, etc., currently. Hope it will become the case again in the future.

  21. dig12345 commented on Oct 6, 2025

    @dig12345

    The solution is to work in the WSL filesystem, and Microsoft recommends that you do this whenever you open VS Code.

    The problem with the WSL filesystem is that it is essentially temporal. A change to the windows user profile or an App Store app update can cause the filesystem to spontaneously vanish. There is a conflict between viewing a WSL image as a disposable container vs a persistent file store for one's work. Which is it? Additionally using the WSL filesystem from within windows is just as glitchy, so that leaves us with no cross-platform fully functional filesystem available. That is a very limiting factor to the WSL ecosystem IMO.

  22. adamkerz commented on Oct 7, 2025

    @adamkerz

    VS Code

    ??? What does that have to do with anything? I'm not using VS Code and why should I?

    Using WSL filesystem is not an acceptable solution, VS Code or otherwise?

  23. Wardrop commented on Nov 21, 2025

    @Wardrop

    +1 from me. I'm having to configure polling for everything due to inotify not working. I'm not familiar with many use cases of WSL/WSL2 other than for linux development on Windows, specifically for web development. This should be of higher priority in my opinion.

    The main problem with using the linux file system I find is data protection. I typically host my development directory with all my projects within a synced folder (e.g. OneDrive) on Windows, like anything else important on my windows machine, so I don't even have to think about. As I don't regularly collaborate with other developers, I'm only committing changes to git when hitting specific milestone or wanting to push out a release. Storing my uncommitted code within WSL therefore to me seems dangerous, unless I configure some kind of sync/backup regime which I'll need to periodically check or configure alerts for if it fails.

    It's not an unsolvable problem, but it's more moving parts and more to configure and think about than I would have to compared to having my source files on Windows.

  24. KenBrannigan commented on Jan 1, 2026

    @KenBrannigan

    I can't believe that we are still waiting for this after 6 years! When is this going to get done?

  25. pdcmoreira commented on Jan 2, 2026

    @pdcmoreira

    Storing my uncommitted code within WSL therefore to me seems dangerous, unless I configure some kind of sync/backup regime which I'll need to periodically check or configure alerts for if it fails.

    You're avoiding the best possible data protection method at your disposal (regardless of WSL or Windows), which is commiting/pushing your code and then you are trying to make up for it with clunkier and less reliable methods.

    I've had corrupted project files before, but that had nothing to do with WSL at all, it was purely at Windows/NTFS level.
    I've never had corrupted WSL files so far, even through WSL crashes.
    The only thing that always gave me peace of mind was always commiting and pushing the code, rigorously.

    Now I completely moved on to Linux and everything is working flawlessly so far, zero headaches, it even feels more stable than Windows ever did. But the git discipline never changed.

  26. fanxing-6 commented on Mar 11, 2026

    @fanxing-6

    Surprisingly, it's still not fixed

  27. badandyomega commented on May 24, 2026

    @badandyomega

    Adding a 2026-05 repro from a Docker-Desktop-on-WSL2 dev setup. Two
    data points the original report doesn't cover:

    1. The inotify channel is broken regardless of write origin, not
      just for Windows-app writes. In our setup, touches from inside the
      container itself and from a sibling container sharing the same
      bind mount also fail to produce inotify events. Polling sees all
      three identically.
    2. Docker Desktop bind mounts inherit the problem. Bind-mounting
      C:\... into a Linux container under Docker Desktop's WSL2
      backend exposes the same behavior, which means HMR / live reload
      is broken not just under bare /mnt/c access but under the very
      common containerized-dev pattern as well.

    Environment

    • Windows 11 Home, build 10.0.26200
    • Docker Desktop 4.73.1 (226574), WSL2 backend
    • Docker Engine 29.4.3
    • Container: Debian 12 (bookworm), kernel
      6.6.87.2-microsoft-standard-WSL2, Node.js 20.20.2
    • fs.inotify.max_user_watches inside container: 1048576

    Minimal reproduction (~30 lines, no bundler)

    // probe.js -- run inside the container:
    //   node probe.js /absolute/path/inside/container/file
    const fs = require('fs');
    const path = require('path');
    
    const TARGET = process.argv[2];
    if (!TARGET) { console.error('usage: node probe.js <abs-file-path>'); process.exit(2); }
    const DIR = path.dirname(TARGET);
    
    console.log(`[probe] file: ${TARGET}`);
    try {
      fs.watch(TARGET, (e, n) => console.log(`[fs.watch FILE] ${new Date().toISOString()} event=${e} name=${n}`));
      console.log('[probe] fs.watch(file) registered OK');
    } catch (err) { console.log(`[probe] fs.watch(file) FAILED: ${err.message}`); }
    try {
      fs.watch(DIR, (e, n) => console.log(`[fs.watch DIR]  ${new Date().toISOString()} event=${e} name=${n}`));
      console.log('[probe] fs.watch(dir) registered OK');
    } catch (err) { console.log(`[probe] fs.watch(dir) FAILED: ${err.message}`); }
    fs.watchFile(TARGET, { interval: 1000 }, (curr, prev) => {
      if (curr.mtimeMs !== prev.mtimeMs) {
        console.log(`[fs.watchFile]  ${new Date().toISOString()} mtime ${new Date(prev.mtimeMs).toISOString()} -> ${new Date(curr.mtimeMs).toISOString()}`);
      }
    });
    console.log('[probe] fs.watchFile registered OK (1s poll)');
    setInterval(() => console.log(`[probe] heartbeat ${new Date().toISOString()}`), 10000);

    Repro steps

    # Terminal 1: start the probe
    docker compose exec -T app node /probe.js /app/some/file.txt
    
    # Terminal 2: touch the file three different ways
    docker compose exec -T app    touch /app/some/file.txt       # same container
    docker compose exec -T other  touch /app/some/file.txt       # sibling container, same bind mount
    touch "C:/host/path/to/some/file.txt"                        # Windows host

    Observed

    [probe] file: /app/packages/app/app/(auth)/welcome/index.tsx
    [probe] fs.watch(file) registered OK
    [probe] fs.watch(dir) registered OK
    [probe] fs.watchFile registered OK (1s poll)
    [probe] heartbeat 2026-05-24T00:00:23.723Z
    [fs.watchFile]    2026-05-24T00:00:32.723Z  mtime ... -> 2026-05-24T00:00:32.717Z   <-- same-container touch
    [probe] heartbeat 2026-05-24T00:00:33.723Z
    [fs.watchFile]    2026-05-24T00:00:36.725Z  mtime ... -> 2026-05-24T00:00:36.070Z   <-- sibling-container touch
    [fs.watchFile]    2026-05-24T00:00:39.729Z  mtime ... -> 2026-05-24T00:00:39.124Z   <-- Windows-host touch
    [probe] heartbeat 2026-05-24T00:00:43.723Z
    

    Three writes, three fs.watchFile polling hits, zero fs.watch
    inotify events.

    Workarounds tried that don't help

    • CHOKIDAR_USEPOLLING=1 (confirms the broken channel is OS-level,
      not bundler-config-level)
    • Restarting the container, the Docker engine, and the host
    • Routing all three write paths separately (same-container, sibling
      container, Windows host) — all three see polling fire and inotify
      stay silent

    Happy to provide further diagnostics if useful (stat -c '%y' cross
    checks, cat /proc/mounts from inside the container, strace of the
    fs.watch registration showing what filesystem the inotify watch was
    attached to, etc.).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    featurewsl2Issue/feature applies to WSL 2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions