Skip to content

Warn the user if VMP is not installed when create instance fails - #41357

Open
Feng Wang (chemwolf6922) wants to merge 4 commits into
masterfrom
user/chemwolf6922/warn-the-user-if-VMP-is-not-installed-before-creating-the-VM
Open

Warn the user if VMP is not installed when create instance fails#41357
Feng Wang (chemwolf6922) wants to merge 4 commits into
masterfrom
user/chemwolf6922/warn-the-user-if-VMP-is-not-installed-before-creating-the-VM

Conversation

@chemwolf6922

@chemwolf6922 Feng Wang (chemwolf6922) commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Summary of the Pull Request

In some rare cases, the VirtualMachinePlatform feature could be left in a broken state, potentially by Windows updates. Where the WSL VM boots normally but hvsockets do not work. Resulting in HCS_E_CONNECTION_TIMEOUT. And it could be resolved by re-enabling the feature. As shown in #41346

This PR adds a VMP component check after a create instance failure. And warns the user if VMP is not enabled. To help the user potentially solving the failure.
This PR also renames the old user message to better reflect its content. And uses its name for this new warning.
This PR also adds the DISM check to the installer step. So, it checks both services and the component when deciding if the component should be installed.

PR Checklist

  • Closes: HCS_E_CONNECTION_TIMEOUT after some Windows 11 updates #41346
  • Communication: I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected
  • Tests: Added/updated if needed and all pass
  • Localization: All end user facing strings can be localized
  • Dev docs: Added/updated if needed
  • Documentation updated: If checked, please file a pull request on our docs repo and link it here: #xxx

Detailed Description of the Pull Request / Additional comments

Validation Steps Performed

Tested locally by injecting a failure into create instance.
image
image

@chemwolf6922
Feng Wang (chemwolf6922) requested a review from a team as a code owner August 14, 2026 09:10
Copilot AI lite review requested due to automatic review settings August 14, 2026 09:10
@chemwolf6922 Feng Wang (chemwolf6922) changed the title User/chemwolf6922/warn the user if vmp is not installed before creating the vm Warn the user if VMP is not installed when create instance fails Aug 14, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves WSL 2 diagnostics and installation checks around the VirtualMachinePlatform (VMP) optional feature, aiming to better guide users when VM creation/initialization fails due to VMP being disabled or partially unavailable.

Changes:

  • Adds a post-failure VMP feature-state check during WSL 2 instance creation and emits a user warning when VMP appears disabled.
  • Refines/renames the networking-related VMP warning used during VM initialization fallback behavior.
  • Extends the installer’s “missing optional components” detection by checking VMP via DISM feature state in addition to existing service-presence checks.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/windows/service/exe/WslCoreVm.cpp Switches the networking fallback warning to a newly named string.
src/windows/service/exe/LxssUserSession.cpp On WSL 2 instance creation failure, checks VMP state and emits a user warning/notification.
src/windows/common/WslInstall.h Adds a new helper API to query whether an optional component is installed/enabled.
src/windows/common/WslInstall.cpp Implements DISM-based feature-state query and uses it in missing-component detection.
localization/strings/en-US/Resources.resw Adds a new string and repurposes an existing VMP-related string key.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +967 to +970
<data name="MessageVirtualMachinePlatformNotInstalled" xml:space="preserve">
<value>Virtual Machine Platform is not enabled. WSL 2 may not work correctly. To enable it, run: wsl.exe --install --no-distribution</value>
<comment>{Locked="WSL 2"}{Locked="wsl.exe"}{Locked="--install "}{Locked="--no-distribution"}Command line arguments, file names and string inserts should not be translated</comment>
</data>

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A new localization change should update the old ones.
Blue (@OneBlue) . Could you please help confirm this? Thanks.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that's correct. Only the en-US version should be added in this PR

Comment thread src/windows/service/exe/LxssUserSession.cpp
Comment thread src/windows/common/WslInstall.cpp Outdated
Copilot AI review requested due to automatic review settings August 14, 2026 09:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Suppressed comments (4)

localization/strings/en-US/Resources.resw:969

  • MessageVirtualMachinePlatformNotInstalled is being repurposed to a new meaning (“VMP is not enabled / WSL 2 may not work correctly”). Existing localized resource files still translate this key with the old networking-specific meaning (e.g. localization/strings/fr-FR/Resources.resw around line 970 still says “Failed to start virtual networking…”), so non-en-US users will see an incorrect warning.

To keep translations correct, avoid changing the meaning of an existing resource key. Add a new resource key for this new warning (and update the new call site to use it), while keeping MessageVirtualMachinePlatformNotInstalled’s existing value/meaning stable (or keep using it for the networking failure path).

  <data name="MessageVirtualMachinePlatformNotInstalled" xml:space="preserve">
    <value>Virtual Machine Platform is not enabled. WSL 2 may not work correctly. To enable it, run: wsl.exe --install --no-distribution</value>
    <comment>{Locked="WSL 2"}{Locked="wsl.exe"}{Locked="--install "}{Locked="--no-distribution"}Command line arguments, file names and string inserts should not be translated</comment>

src/windows/service/exe/LxssUserSession.cpp:2740

  • This warning emits MessageVirtualMachinePlatformNotInstalled(), but that resource key historically meant “virtual networking failed; install VMP…”, and is already translated that way in many non-en-US .resw files (e.g. fr-FR/es-ES). With the updated en-US value, non-en-US users will see the old networking-related translation here.

Prefer introducing a new resource key for this new “VMP not enabled / WSL 2 may not work correctly” warning, and keep the existing key’s meaning stable to preserve translations.

                        if (!WslInstall::IsOptionalComponentInstalled(WslInstall::c_optionalFeatureNameVmp))
                        {
                            wsl::windows::common::notifications::DisplayOptionalComponentsNotification();
                            EMIT_USER_WARNING(wsl::shared::Localization::MessageVirtualMachinePlatformNotInstalled());
                        }

src/windows/common/WslInstall.cpp:278

  • IsOptionalComponentInstalled() throws if it can’t find/parse the State : line in DISM output. Since this is a best-effort diagnostic/helper (and is used in installer prereq detection), returning false with a log is safer than aborting the whole operation on an unexpected output format.

    THROW_HR_MSG(E_UNEXPECTED, "Failed to parse optional component state: %ls", component);

src/windows/common/WslInstall.cpp:265

  • IsOptionalComponentInstalled() currently throws if DISM returns a non-zero exit code. This helper is used by CheckForMissingOptionalComponents() (invoked before elevation in the install flow), so throwing here can cause wsl.exe --install to fail outright due to a transient DISM error instead of falling back to the existing service-based checks.

Consider treating DISM failures as “unknown/not installed” (log and return false) rather than throwing.

This issue also appears on line 277 of the same file.

    const auto result = process.RunAndCaptureOutput();
    THROW_HR_IF_MSG(
        HRESULT_FROM_WIN32(result.ExitCode), result.ExitCode != ERROR_SUCCESS, "Failed to query optional component: %ls", component);

Copilot AI review requested due to automatic review settings August 14, 2026 09:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

Suppressed comments (3)

localization/strings/en-US/Resources.resw:970

  • MessageVirtualMachinePlatformNotInstalled is now being used for a different meaning than the existing translations in other locales (e.g. es-ES still translates it as the old “Failed to start virtual networking…” message). This will cause non-en-US users to see an incorrect/misleading warning. To avoid breaking existing translations, keep the existing key’s meaning stable (or leave it unused) and introduce a new resource key for the new “VMP is not enabled / WSL 2 may not work correctly” warning, then update the new call site(s) to use that new key.
  <data name="MessageVirtualMachinePlatformNotInstalled" xml:space="preserve">
    <value>Virtual Machine Platform is not enabled. WSL 2 may not work correctly. To enable it, run: wsl.exe --install --no-distribution</value>
    <comment>{Locked="WSL 2"}{Locked="wsl.exe"}{Locked="--install "}{Locked="--no-distribution"}Command line arguments, file names and string inserts should not be translated</comment>
  </data>

src/windows/common/WslInstall.cpp:280

  • IsOptionalComponentInstalled() throws on DISM failures/timeouts and on parse failures. This function is now called from CheckForMissingOptionalComponents() during install prerequisite checks, so a transient DISM error/timeout can cause wsl --install to fail early instead of proceeding (or treating the feature as missing). Consider making this a best-effort query that logs and returns false on failure.
    std::wstring systemDirectory;
    THROW_IF_FAILED(wil::GetSystemDirectoryW(systemDirectory));

    const auto dismPath = std::filesystem::path(std::move(systemDirectory)) / L"dism.exe";
    const auto commandLine = std::format(L"{} /Online /English /Get-FeatureInfo /FeatureName:{}", dismPath.native(), component);

src/windows/service/exe/LxssUserSession.cpp:2743

  • This adds a DISM call (up to 30s timeout) on every WSL2 CreateInstance exception path before rethrowing. That can significantly delay unrelated failures and add extra noise. Since the motivating scenario is HCS_E_CONNECTION_TIMEOUT, consider gating the DISM query/warning on the specific failure HRESULT stored in result.
                if (version == LXSS_WSL_VERSION_2)
                {
                    try
                    {
                        if (!WslInstall::IsOptionalComponentInstalled(WslInstall::c_optionalFeatureNameVmp))

Comment on lines +967 to +970
<data name="MessageVirtualMachinePlatformNotInstalled" xml:space="preserve">
<value>Virtual Machine Platform is not enabled. WSL 2 may not work correctly. To enable it, run: wsl.exe --install --no-distribution</value>
<comment>{Locked="WSL 2"}{Locked="wsl.exe"}{Locked="--install "}{Locked="--no-distribution"}Command line arguments, file names and string inserts should not be translated</comment>
</data>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes that's correct. Only the en-US version should be added in this PR

std::wstring systemDirectory;
THROW_IF_FAILED(wil::GetSystemDirectoryW(systemDirectory));

const auto dismPath = std::filesystem::path(std::move(systemDirectory)) / L"dism.exe";

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we want to add a dependency on parsing dism's output. It doesn't seem to be designed to be parsed by a program and I'd be worried that its format could change at some point.

The root cause of the associated problem seems to be a broken Windows installation where some of VMP was enabled, and some of it was broken. If we want to detect these kind of "broken OC state", I think the easiest would be to use something like DismGetFeatureInfo and look at its output. Sadly we don't have the ADK easily available so we'll have to manually load dismapi for it.

Once we have this implemented, we could add that call at the end of IsVirtualMachinePlatformInstalled(), so all existing calls will detect when VMP is in a bad state

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants