In the previous post, I covered how to license a standalone ESX 9.0 host by importing a private license file directly on the host with esxcli. That workflow was straightforward: generate a keypair, grab a license file from the portal, scp both files to the host, run two esxcli commands, done.
VCF 9.1 changes everything.
Starting with 9.1, you cannot generate individual ESX host licenses from the VCF Business Services console and apply them directly. Instead, Broadcom introduced a License Server appliance — a small OVA that sits between the portal and your hosts. You import your private license file into the License Server, and the License Server issues host-scoped licenses to each ESX host via API.
This post walks through the full end-to-end workflow based on the official VCF 9.1 Licensing – Private License Files documentation.
The Big Disclaimer (Again)
Same rules apply from the previous post:
- You need a valid subscription/entitlement
- You need access to the VCF Business Services licensing portal
- You must be approved for private license files
If you don’t have entitlements, this won’t help — and it shouldn’t.
What Changed in 9.1 vs 9.0
| VCF 9.0 | VCF 9.1 | |
|---|---|---|
| License delivery | Direct private license file → ESX host | License Server OVA → host-scoped licenses |
| esxcli workflow | Import key + token directly on host | Import host-scoped token from License Server |
| License Server | Not required for standalone hosts | Required — even without VCF Operations |
| Portal license type | “ESX host” | “License server and standalone hosts without VCF Operations (9.1+)” |
| 9.0 → 9.1 upgrade | N/A | Host loses its license and is not in evaluation mode — you must complete the new workflow before workloads can run |
⚠️ Critical: If you upgrade a standalone host from 9.0 to 9.1, the host loses its license immediately and is not placed in evaluation mode. You cannot start workloads until the new licensing workflow is complete. Plan accordingly.
High-Level Workflow
Here’s the 30,000-foot view before we dive into each step:
- Deploy the License Server OVA (can run on any vCenter, even pre-9.x)
- Generate an RSA keypair for the License Server
- Create a Private License File in the VCF Business Services portal (type: standalone hosts)
- Import the private key into the License Server (via API)
- Import the license file into the License Server (via API)
- Get the host ID from the ESX 9.1 host (ESXCLI)
- Get the core count from the ESX host (ESXCLI)
- Request a host-scoped license from the License Server (API)
- Download the host-scoped license from the License Server (API)
- Apply the host-scoped license to the ESX host (ESXCLI)
What You Need
- A vCenter instance (any version, even pre-9.x) to deploy the License Server OVA
- The License Server OVA file from support.broadcom.com
- SSH access to the ESX 9.1 host
- A machine with
opensslandcurl(or PowerShell) - Access to the VCF Business Services console
Step 1 — Deploy the License Server OVA
Download the License Server OVA from support.broadcom.com and deploy it in any vCenter instance.
During the OVA deployment, pay attention to these settings under Customize template:
| Setting | Value |
|---|---|
| Unique Registration Key (under Application) | Set to NA |
| API Key (under Advanced Configuration) | Set a unique client secret — you’ll need this for every API call |
💡 Tip: Treat the API Key like a password. You’ll use it as an
X-API-Keyheader in every API call to the License Server.
Step 2 — Generate an RSA Key Pair
Same as before — generate a 4096-bit RSA keypair:
openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:4096
openssl rsa -pubout -in private_key.pem -out public_key.pem
Optionally combine them:
cat private_key.pem public_key.pem > keypair.pem
🔐 Keep both keys safe. The portal does not save the public key unless you explicitly check “Save Public Keys” during the wizard.
Step 3 — Create a Private License File in the Portal
Log in to the VCF Business Services console and:
- Navigate to License Management → VCF Operations Registrations
- Click Create Private License File
- In the Define Private License File section:
- Enter a display name
- Max VCF Version: select 9.1 (or higher)
- Licensed Environment: select “License server and standalone hosts without VCF Operations (9.1+)”
- Click Save
- In the Allocate Licenses section:
- Enter a display name for the license server (doesn’t need to match the hostname)
- Select the licenses to allocate, click Confirm
- In the Download and Import Private License File section:
- Paste the encoded RSA public key (PEM format) under “Enter Public Key for Standalone License Server”
- (Optional) Check Save Public Keys
- Click Download to get the license file
- Click Done
⚠️ Wrong license type = failure. If you select “VCF Operations with license servers” instead of the standalone option, the license assignment will fail when you try to use it.
Step 4 — Import the Private Key into the License Server
Use the License Server API to import your private key:
Bash (curl):
# Variables
LS_IP="10.1.2.3" # License Server IP or FQDN
API_KEY="your-api-key-here" # The API Key from OVA deployment
KEY_PATH="/path/to/private_key.pem" # Path to the private key
curl -X POST "https://$LS_IP/lss/external/api/v1/identity/key" \
-H "X-API-Key: $API_KEY" \
-F "file=@$KEY_PATH"
PowerShell:
# Variables
$licenseServer = "license-server.example.local"
$apiKey = "your-api-key-here"
$privateKeyPemFilePath = "C:\path\to\private_key.pem"
$headers = @{ "X-API-Key" = $apiKey }
Invoke-RestMethod -Uri "https://$licenseServer/lss/external/api/v1/identity/key" `
-Method Post `
-Headers $headers `
-Form @{ file = Get-Item $privateKeyPemFilePath }
Step 5 — Import the License File into the License Server
Now import the license file you downloaded from the portal:
Bash (curl):
LS_IP="10.1.2.3"
API_KEY="your-api-key-here"
LIC_PATH="/path/to/vcf-license.lic"
curl -X POST "https://$LS_IP/lss/external/api/v1/license" \
-H "X-API-Key: $API_KEY" \
-F "file=@$LIC_PATH"
PowerShell:
$licenseServer = "license-server.example.local"
$apiKey = "your-api-key-here"
$licenseFilePath = "C:\path\to\vcf-license.lic"
$headers = @{ "X-API-Key" = $apiKey }
Invoke-RestMethod -Uri "https://$licenseServer/lss/external/api/v1/license" `
-Method Post `
-Headers $headers `
-Form @{ file = Get-Item $licenseFilePath }
Step 6 — Get the Host ID and Core Count from the ESX Host
SSH into the ESX 9.1 host and grab two pieces of information:
Get the host hardware ID:
esxcli licensing host id get
Get the core count:
esxcli hardware cpu global get
Look for the CPU Cores value. Write both down — you’ll need them for the next API call.
Step 7 — Get the Available Allocations from the License Server
Before you can request a host-scoped license, you need to know which license allocation to use:
Bash (curl):
LS_IP="10.1.2.3"
API_KEY="your-api-key-here"
curl -X GET "https://$LS_IP/lsc/entitlements/standalone" \
-H "X-API-Key: $API_KEY"
PowerShell:
$licenseServer = "license-server.example.local"
$apiKey = "your-api-key-here"
$headers = @{ "X-API-Key" = $apiKey }
Invoke-RestMethod -Uri "https://$licenseServer/lsc/entitlements/standalone" `
-Method Get `
-Headers $headers
Note the allocation_id from the response — you’ll need it next.
Step 8 — Request a Host-Scoped License
Now tie it all together. Use the allocation ID, host ID, and core count to request a host-scoped license:
Bash (curl):
LS_IP="10.1.2.3"
API_KEY="your-api-key-here"
ALLOC_ID="3fa85f64-5717-4562-b3fc-2c963f66afa6" # From Step 7
HOST_ID="642351e9-a7ac-48af-98f0-18d373e3528f" # From Step 6
USAGE=32 # Core count from Step 6
curl -X POST "https://$LS_IP/lsc/entitlements/standalone/assignments" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"allocation_id\": \"$ALLOC_ID\",
\"assets\": [
{
\"id\": \"$HOST_ID\",
\"product_family\": \"VMware ESX Server\",
\"product_family_version\": \"9.1\",
\"usage\": $USAGE
}
]
}"
PowerShell:
$licenseServer = "license-server.example.local"
$apiKey = "your-api-key-here"
$allocationId = "3fa85f64-5717-4562-b3fc-2c963f66afa6"
$hostHardwareId = "642351e9-a7ac-48af-98f0-18d373e3528f"
$coreUsage = 32
$headers = @{
"X-API-Key" = $apiKey
"Content-Type" = "application/json"
}
$body = @{
allocation_id = $allocationId
assets = @(
@{
id = $hostHardwareId
product_family = "VMware ESX Server"
product_family_version = "9.1"
usage = $coreUsage
}
)
} | ConvertTo-Json
Invoke-RestMethod -Uri "https://$licenseServer/lsc/entitlements/standalone/assignments" `
-Method Post `
-Headers $headers `
-Body $body
Step 9 — Download the Host-Scoped License
Download the license that was just generated for your specific host:
Bash (curl):
LS_IP="10.1.2.3"
API_KEY="your-api-key-here"
HOST_ID="642351e9-a7ac-48af-98f0-18d373e3528f"
curl -X GET "https://$LS_IP/lsc/assets/standalone/$HOST_ID/entitlement" \
-H "X-API-Key: $API_KEY" \
-o /tmp/host-scoped-entitlement.token
PowerShell:
$licenseServer = "license-server.example.com"
$apiKey = "your-api-key-here"
$hostId = "642351e9-a7ac-48af-98f0-18d373e3528f"
$headers = @{ "X-API-Key" = $apiKey }
Invoke-RestMethod -Uri "https://$licenseServer/lsc/assets/standalone/$hostId/entitlement" `
-Method Get `
-Headers $headers `
-OutFile "host-scoped-entitlement.token"
Copy the downloaded token to the ESX host:
scp /tmp/host-scoped-entitlement.token root@<esx-host>:/tmp/
Step 10 — Apply the Host-Scoped License on the ESX Host
SSH into the ESX host and apply the token:
esxcli licensing entitlement add --file /tmp/host-scoped-entitlement.token
Verify it:
esxcli licensing entitlement list
Your host should now show a valid license. 🎉
Complete Bash Script
Here’s a consolidated script that covers the License Server API steps (4–9). Run this from a workstation that can reach both the License Server and the ESX host:
#!/bin/bash
set -euo pipefail
# ── Configuration ──────────────────────────────────────
LS_IP="10.1.2.3" # License Server IP/FQDN
API_KEY="your-api-key-here" # License Server API Key
KEY_PATH="/tmp/private_key.pem" # RSA private key
LIC_PATH="/tmp/vcf-license.lic" # License file from portal
ESX_HOST="root@esx-host.example.local" # ESX host SSH target
# ── Step 4: Import private key into License Server ─────
echo ">>> Importing private key into License Server..."
curl -s -X POST "https://$LS_IP/lss/external/api/v1/identity/key" \
-H "X-API-Key: $API_KEY" \
-F "file=@$KEY_PATH"
# ── Step 5: Import license file into License Server ────
echo -e "\n>>> Importing license file into License Server..."
curl -s -X POST "https://$LS_IP/lss/external/api/v1/license" \
-H "X-API-Key: $API_KEY" \
-F "file=@$LIC_PATH"
# ── Step 6: Get host ID and core count from ESX host ───
echo -e "\n>>> Getting host ID from ESX host..."
HOST_ID=$(ssh "$ESX_HOST" "esxcli licensing host id get" | awk '{print $NF}')
echo "Host ID: $HOST_ID"
CORE_COUNT=$(ssh "$ESX_HOST" "esxcli hardware cpu global get" | grep "CPU Cores" | awk '{print $NF}')
echo "Core Count: $CORE_COUNT"
# ── Step 7: Get available allocations ──────────────────
echo -e "\n>>> Getting available allocations..."
ALLOC_RESPONSE=$(curl -s -X GET "https://$LS_IP/lsc/entitlements/standalone" \
-H "X-API-Key: $API_KEY")
echo "$ALLOC_RESPONSE" | python3 -m json.tool
# NOTE: You'll need to extract the allocation_id from the response above.
# Replace the value below with the actual allocation_id.
ALLOC_ID="REPLACE_WITH_ALLOCATION_ID"
# ── Step 8: Request host-scoped license ────────────────
echo -e "\n>>> Requesting host-scoped license..."
curl -s -X POST "https://$LS_IP/lsc/entitlements/standalone/assignments" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"allocation_id\": \"$ALLOC_ID\",
\"assets\": [
{
\"id\": \"$HOST_ID\",
\"product_family\": \"VMware ESX Server\",
\"product_family_version\": \"9.1\",
\"usage\": $CORE_COUNT
}
]
}"
# ── Step 9: Download host-scoped license ───────────────
echo -e "\n>>> Downloading host-scoped license..."
curl -s -X GET "https://$LS_IP/lsc/assets/standalone/$HOST_ID/entitlement" \
-H "X-API-Key: $API_KEY" \
-o /tmp/host-scoped-entitlement.token
# ── Step 10: Apply to ESX host ─────────────────────────
echo -e "\n>>> Copying token to ESX host and applying..."
scp /tmp/host-scoped-entitlement.token "$ESX_HOST":/tmp/
ssh "$ESX_HOST" "esxcli licensing entitlement add --file /tmp/host-scoped-entitlement.token"
ssh "$ESX_HOST" "esxcli licensing entitlement list"
echo -e "\n✅ Done. Host should now be licensed."
Upgrading from 9.0 to 9.1? Extra Steps
If you’re upgrading a standalone host that was previously licensed under the 9.0 workflow (from the previous post):
- Deploy a License Server OVA (Steps 1–2 above)
- In the VCF Business Services console, edit your existing private registration:
- Update Max VCF Version to 9.1
- Change Licensed Environment to “License server and standalone hosts without VCF Operations”
- Provide the new public key for the License Server
- Download the new license file
- Import the license file into the License Server (Step 5)
- Upgrade the host to ESX 9.1
- Complete Steps 6–10 to apply the host-scoped license
⚠️ After the upgrade, the host has no license and is NOT in evaluation mode. VMs will not power on. Complete the licensing workflow before upgrading, or plan for downtime.
Reclaiming License Capacity
If you reinstall an ESX host, replace hardware, or decommission a server, you’ll need to reclaim the license capacity from the License Server so it can be reassigned:
# Get current license assignments for a host
curl -X GET "https://$LS_IP/lsc/assets/standalone/$HOST_ID/entitlement" \
-H "X-API-Key: $API_KEY"
Consult the official PDF (page 25) for the full reclaim procedure — it requires additional API calls with the allocation ID.
License Server Maintenance Notes
- License Servers cannot be updated in-place. If you need a newer version, deploy a new OVA and re-import your keys and license file.
- The License Server can run on any vCenter instance, including pre-9.x versions.
- Existing host licenses are not affected when you swap the License Server appliance.
- You can use the same public/private key pair on the new License Server, or generate new ones.
Common Gotchas
- Wrong Licensed Environment type: If you select “VCF Operations with license servers” instead of “License server and standalone hosts without VCF Operations (9.1+)”, the license won’t work for standalone hosts.
- Forgot the API Key during OVA deployment: You can update it later via vApp Options on the License Server VM (must be powered off first).
- Host loses license after 9.0 → 9.1 upgrade: This is by design. The host is not placed in evaluation mode. Complete the licensing workflow before or immediately after the upgrade.
- Trying the old 9.0 direct-apply workflow: The
esxcli licensing credential add+esxcli licensing entitlement addapproach from 9.0 no longer works for portal-generated license files. You must go through the License Server. - Self-signed certs on the License Server: You may need
-k/--insecurewith curl, orInvoke-RestMethod -SkipCertificateCheckin PowerShell.
References
- VCF 9.1 Licensing – Private License Files (official PDF) — VCF Business Services
- VCF 9.0 Licensing – Private License Files (previous version) — VCF Business Services
- Broadcom ESXCLI licensing command reference — Broadcom Developer
- Previous post: License a Standalone ESX 9.0 Host — cosmin.us