Edit

Error 0xC004F074 - "No Key Management Service (KMS) could be contacted"

Applies to: ✔️ Windows VMs

Summary

This article explains how to resolve error 0xC004F074 that occurs when you try to activate a Windows virtual machine (VM) in Microsoft Azure.

Important

If you're experiencing Azure virtual machine (VM) Windows activation issues, see Troubleshooting tools for Windows activation issues on Azure virtual machines.

Prerequisites

Symptoms

When you try to activate a Microsoft Azure Windows VM, you see the following error message in Windows Script Host:

**Error: 0xC004F074** The Software Licensing Service reported that the computer could not be activated. No Key Management Service (KMS) could be contacted. Please see the Application Event Log for additional information.

Cause

The VM can't connect to the KMS service for activation. If you use an Azure KMS for activation (the default selection), the activation request must come from an Azure public IP address. Possible causes for this connectivity failure include:

  • Forced tunneling, in which you route all traffic outside Azure (typically to an on-premises environment) by using either Azure ExpressRoute or a network virtual appliance.

  • Traffic that's blocked by either a network virtual appliance or a standard internal load balancer.

Investigation

To determine the specific cause of the problem, follow these steps.

Step 1: Configure the appropriate KMS client setup key

Note

This step isn't required for VMs that run Windows 10 Enterprise multi-session (also known as Windows 10 Enterprise for Virtual Desktops) in Azure Virtual Desktop.

To determine whether your VM is running the multi-session edition, run the following Software License Manager script command:

slmgr.vbs /dlv

If the output contains the Name: Windows(R), ServerRdsh edition string, the VM is running the multi-session edition, and you can skip the rest of this step.

Note

If you deploy a Windows 10 Enterprise multi-session VM, and then you update the product key to another edition, you can't revert the VM to Windows 10 Enterprise multi-session. Instead, you have to redeploy the VM. For more information, see Can I upgrade a Windows VM to Windows Enterprise multi-session?.

For the VM that you create from a custom image, you must configure the appropriate KMS client setup key for the VM.

  1. In an elevated Command Prompt window, run the following Software License Manager script command:

    cscript c:\windows\system32\slmgr.vbs /dlv
    
  2. Check the Description value in the output to determine whether the VM was created from retail (RETAIL channel) or volume (VOLUME_KMSCLIENT) license media.

  3. If the previous command output indicates the RETAIL channel, run the following Software License Manager script commands. The first command sets the KMS client setup key for the version of Windows Server that you use. The second command forces another activation attempt.

    cscript c:\windows\system32\slmgr.vbs /ipk <kms-client-setup-key>
    cscript c:\windows\system32\slmgr.vbs /ato
    

    For example, if you're using Windows Server 2016 Datacenter, the first command appears as follows:

    cscript c:\windows\system32\slmgr.vbs /ipk CB7KF-BWN84-R7R2Y-793K2-8XDDG
    

Step 2: Check whether the VM is behind a Standard SKU internal load balancer

To check whether the VM is behind a Standard SKU internal load balancer that blocks outbound internet traffic by default, follow these steps:

  1. In the Azure portal, search for and select Virtual machines.

  2. In the list of virtual machines, select the name of your VM.

  3. In the menu pane for your VM, locate the Networking heading, and then select Load balancing. If you see a message that states No load balancing resources to display, then the VM isn't behind any load balancer. In this case, you can go to Step 3: Verify the connectivity between the VM and Azure KMS service.

  4. If you see a load balancer resource, select the name of the load balancer to go to the load balancer's Overview page.

  5. In the menu pane of the load balancer, select Properties.

  6. On the Properties page, locate the values for SKU and Load Balancing Type, and then see the following table for conclusions.

    Values of SKU and Load Balancing Type Conclusion
    The SKU value is Standard, and the Load Balancing Type value is Private. The VM is behind a Standard SKU internal load balancer that blocks outbound internet traffic by default. To enable outbound connectivity, go to Solution 2 (for standard internal load balancer): Use a network address translation (NAT) gateway or a standard public load balancer.
    The SKU value isn't Standard, and the Load Balancing Type value is Public. The VM isn't behind a Standard SKU internal load balancer, and outbound internet traffic isn't blocked by default. Go to Step 3: Verify the connectivity between the VM and Azure KMS service.

Step 3: Verify the connectivity between the VM and Azure KMS service

  1. Clear the existing KMS server configurations, and make sure that the VM is configured to use the correct Azure KMS server. To make this check, run the following Software License Manager script command:
   slmgr.vbs /ckms
   Invoke-Expression "$env:windir\system32\cscript.exe $env:windir\system32\slmgr.vbs /skms azkms.core.windows.net:1688"

This command returns the following text:

Key Management Service machine name set to azkms.core.windows.net:1688 successfully.

  1. Make sure that the firewall in the VM doesn't block outbound network traffic to the KMS endpoint on port 1688. To check this status, apply one of the following options:
     Test-NetConnection azkms.core.windows.net -port 1688

If the connection attempt is permitted, the cmdlet displays "TcpTestSucceeded: True" in the output text.

  • Check connectivity by running the PsPing tool:
     .\psping.exe azkms.core.windows.net:1688

In the command output, the second-to-last line resembles the following text:

Sent = 4, Received = 4, Lost = 0 (0% loss)

If the Lost value is greater than 0, the VM doesn't have connectivity to the KMS server. In this situation, if the VM is in a virtual network and has a custom DNS server specified, make sure that the DNS server can resolve the azkms.core.windows.net domain name. If it can't, change the DNS server to one that can resolve azkms.core.windows.net.

Note

If you remove all DNS servers from a virtual network, VMs use Azure's internal DNS service. This service can resolve kms.core.windows.net.

  1. Use an Azure Network Watcher next hop test to verify that the next hop type is Internet from the affected VM to particular destinations. To apply the next hop test, follow these steps:

    1. In the Azure portal, search for and select Virtual machines.

    2. In the list of virtual machines, select the name of your VM.

    3. In the menu pane of your VM, locate the Help heading, and then select Connection troubleshoot.

    4. On the Connection troubleshoot page of your VM, specify the following field values.

      Field Value
      Destination type Specify manually
      URI, FQDN, or IP address 20.118.99.224, 40.83.235.53 (for azkms.core.windows.net), or the IP of the appropriate KMS endpoint that applies to your region
      Destination port 1688
      Source port 1688
      Diagnostic tests Next hop
    5. Select Run diagnostic tests.

    6. After the diagnostic tests finish, review the Results box that appears below the button. The Next hop (from source) test should have a Status value of Success, and the Details value should include Next hop type: Internet in the text. If the next hop type is Internet, repeat the next hop test for each of the remaining IPs. However, if the next hop type is shown as VirtualAppliance, VirtualNetworkGateway, or anything other than Internet, one of the following scenarios is probably occurring:

      • A default route exists that routes the traffic outside Azure before the traffic is sent to the Azure KMS endpoint.

      • Traffic is blocked somewhere along the path.

      For these scenarios, go to Solution 1: (for forced tunneling) Use the Azure custom route to route activation traffic to the Azure KMS server.

  2. After you verify that a connection to azkms.core.windows.net is successful, run the following command in the elevated Windows PowerShell window. This command tries to activate the Windows VM several times:

   1..12 | ForEach-Object {
       Invoke-Expression "$env:windir\system32\cscript.exe $env:windir\system32\slmgr.vbs /ato";
       Start-Sleep 5
   }

If the activation attempt is successful, the command displays a message that resembles the following example:

Activating Windows(R), Server Datacenter edition (<kms-client-product-key>) ... Product activated successfully.

Solution

Solution 1 (for forced tunneling): Use the Azure custom route to route activation traffic to the Azure KMS server

If a forced tunneling scenario routes traffic outside Azure, work with your network admin to determine the correct course of action. One possible solution is described in the Solution section of Windows activation fails in forced tunneling scenario. Apply this solution if it's consistent with your organization's policies.

Solution 2 (for standard internal load balancer): Use a network address translation (NAT) gateway or a standard public load balancer

If a standard internal load balancer blocks traffic, two different approaches can fix the problem, as described in Use Source Network Address Translation (SNAT) for outbound connections:

In production deployments, use an Azure Virtual Network NAT configuration for outbound connectivity. For more information about Azure NAT Gateway, see What is Azure NAT Gateway?

However, if you have to block all internet traffic, make sure that you deny outbound internet access by using a network security group (NSG) rule on the subnet of the VM that you have to activate. Operating system activation traffic to the KMS IPs on port 1688 remains enabled because of platform internal rules.

Solution 3 (for standard internal load balancer): Centralized egress through Azure Firewall without forced tunneling

As mentioned in Solution 2, to overcome SNAT port limitations for outbound connectivity, use an Azure Virtual Network NAT configuration for scalable and resilient outbound traffic management.

If your deployment uses an internal load balancer, and it routes all outbound traffic through Azure Firewall, this solution is applicable. Use it if:

  • You need centralized outbound traffic control.
  • Forced tunneling to on-premises isn't required.
  • A NAT Gateway isn't necessary, unless SNAT port exhaustion occurs.

This pattern is common in environments in which back-end VMs behind an internal load balancer have to access external services (such as KMS servers) through Azure Firewall while maintaining internal routing simplicity. For more information, see Integrate Azure Firewall with Azure Standard Internal Load Balancer.

Flow summary for inbound and outbound traffic

  • Inbound: Client → Internal load balancer → Backend VM → Client
  • Outbound: Backend VM → User Defined Route (0.0.0.0/0) → Azure Firewall → Internet

Steps to perform Windows Activation through Azure Firewall

  1. Verify outbound routing configuration. Make sure that outbound traffic from the VM subnet is routed to Azure Firewall by using a user-defined route (UDR). For example: 0.0.0.0/0 → Azure Firewall.

  2. Add a network rule on Azure Firewall to allow outbound traffic to the KMS server.

    Field Value
    Destination The fully qualified domain name (FQDN) of the KMS server: azkms.core.windows.net, the IP address that azkms.core.windows.net resolves to: 20.118.99.224 or 40.83.235.53, the IP address that kms.core.windows.net resolves to: 23.102.135.246, or the IP address of the appropriate KMS endpoint that applies to your region
    Port 1688
    Protocol TCP
    Action Allow
  3. Verify that the DNS resolution from the VM finishes successfully and returns the correct IP addresses.

  4. Activate Windows by running the following command in an elevated Command Prompt window:

    slmgr.vbs /ato
    
  5. If activation fails, check Azure Firewall diagnostics:

    • Check network rule logs to verify that traffic on port 1688 is allowed.
    • Verify that the rule matches the resolved IP, port, and protocol.
    • Verify that there are no implicit denies or misconfigured rule priorities.