STS token expired or certificate not validMACHINE_SSL_CERTvCenter uses multiple certificates for internal service communication: Machine SSL, STS signing, and solution user certificates. The STS signing certificate, used by the Security Token Service for SSO authentication, has a default 2-year validity. When it expires, no user or service can authenticate, effectively locking out all vCenter management. Unlike external CA certs, VMCA-issued certs are often forgotten because they were auto-provisioned during installation.
Check all certificate expiry dates
# SSH to VCSA, list all trusted certs:
/usr/lib/vmware-vmafd/bin/dir-cli trustedcert list --login administrator@vsphere.local
# Check Machine SSL cert expiry:
/usr/lib/vmware-vmafd/bin/vecs-cli entry getcert \
--store MACHINE_SSL_CERT --alias __MACHINE_CERT | \
openssl x509 -noout -dates
# Check STS signing cert:
/usr/lib/vmware-vmafd/bin/vecs-cli entry getcert \
--store STS_INTERNAL_SSL --alias __MACHINE_CERT | \
openssl x509 -noout -dates
Check vCenter service health and logs
# List all vCenter services and status:
service-control --status
# Check vpxd log for certificate errors:
grep -i "certificate\|expired\|STS" /var/log/vmware/vpxd/vpxd.log | tail -30
# Check SSO log:
grep -i "token\|expired\|cert" /var/log/vmware/sso/ssoAdminServer.log | tail -20
Renew STS signing certificate
# SSH to VCSA as root, run the STS cert renewal script:
# (VMware KB 76719 — fixsts script for vCenter 7.x/8.x)
cd /tmp
python /usr/lib/vmware-vmdir/share/config/fixsts.py
# Restart all services after renewal:
service-control --stop --all
service-control --start --all
Renew Machine SSL and solution user certs via certificate-manager
# Launch interactive certificate manager:
/usr/lib/vmware-vmca/bin/certificate-manager
# Option 3: Replace Machine SSL cert with VMCA certificate
# Option 6: Replace solution user certs with VMCA certificates
# Follow prompts — provide administrator@vsphere.local credentials
# Verify renewed certs:
/usr/lib/vmware-vmafd/bin/vecs-cli entry getcert \
--store MACHINE_SSL_CERT --alias __MACHINE_CERT | \
openssl x509 -noout -dates -subject
Verify services are healthy post-renewal
# Check all services are running:
service-control --status
# Test SSO login via CLI:
/usr/lib/vmware-vmafd/bin/dir-cli trustedcert list \
--login administrator@vsphere.local --password 'YourPassword'
# Verify vSphere Client login works in browser:
# Navigate to https://vcsa.domain.local/ui
openssl x509 -checkend. Document all certificate types and their validity periods. Schedule proactive renewal during maintenance windows well before expiry.
vSphere Lifecycle Manager (vLCM) provides image-based management for ESXi hosts. You define a desired image (ESXi version + vendor addon + components), then vLCM checks compliance and remediates non-compliant hosts by placing them in maintenance mode, applying the image, and rebooting. This replaces the legacy Update Manager baseline approach with a declarative, single-image model.
Check current ESXi version and manage depot
# SSH to ESXi host — check current version:
esxcli system version get
esxcli software profile get
# List installed VIBs:
esxcli software vib list | head -20
# Check boot device free space:
df -h /bootbank
vdf -h
Configure vLCM image and check compliance
# In vSphere Client:
# Cluster → Updates → Image → Setup Image
# Select ESXi version, vendor addon (e.g., Dell OpenManage, HPE)
# Add any required components
# Check compliance:
# Cluster → Updates → Check Compliance
# Review non-compliant hosts and missing components
# PowerCLI — check compliance:
Get-Cluster "ClusterName" | Test-Compliance
Remediate non-compliant hosts
# From vSphere Client:
# Cluster → Updates → Remediate (pre-check runs automatically)
# Review pre-check results — resolve any blockers
# Confirm remediation — hosts enter maintenance mode sequentially
# Manual ESXi update via CLI (alternative):
esxcli software profile update -p ESXi-8.0U2-profile \
-d https://depot.vmware.com/vsphere-8.0/
# Remove incompatible VIBs if needed:
esxcli software vib remove -n incompatible-vib-name
# Reboot after manual update:
reboot
VCSA file-based backup captures the vCenter configuration database, inventory, roles, permissions, and optionally historical stats/events/tasks. The backup is performed via the VAMI (vCenter Appliance Management Interface) at port 5480. For disaster recovery, you deploy a fresh VCSA and select "Restore from backup" during the Stage 2 installer wizard.
Configure scheduled backup in VAMI
# Access VAMI:
# https://vcsa.domain.local:5480 → Backup → Configure
# Backup settings:
# Protocol: SCP (recommended) or FTPS
# Server: backup-server.domain.local
# Path: /vcsa-backups/
# Username / Password for target server
# Encryption password (store securely — required for restore!)
# Schedule: Daily at 02:00, retain 7 backups
# Data to back up: Select "Stats, Events, and Tasks" for full backup
# Or via API (automated):
curl -k -X POST https://vcsa.domain.local:443/api/appliance/recovery/backup/schedules \
-H "vmware-api-session-id: $SESSION" \
-H "Content-Type: application/json" \
-d '{"schedule_id":"daily","recurrence_info":{"hour":2,"minute":0}}'
Trigger manual backup and verify
# Trigger on-demand backup from VAMI:
# VAMI → Backup → Backup Now
# Verify backup files on target server:
ls -lah /vcsa-backups/
# Expected: timestamped directory with .json manifest and .gz data files
# Check backup log on VCSA:
cat /var/log/vmware/applmgmt/backup.log | tail -20
# Validate backup integrity (check manifest):
cat /vcsa-backups/latest/backup-metadata.json
Restore vCenter from backup
# Deploy new VCSA from ISO:
# 1. Mount VCSA installer ISO
# 2. Run installer → Stage 1: Deploy new appliance
# 3. Stage 2: Select "Restore from backup" instead of "Set up"
# 4. Provide backup location (SCP/FTP path) and encryption password
# 5. Select backup to restore from
# 6. Wait for restore to complete and services to start
# Post-restore verification:
service-control --status
# Verify inventory, permissions, and host connectivity in UI
Collect ESXi host support bundle
# SSH to ESXi host — generate support bundle:
vm-support
# Output saved to: /var/tmp/esx-hostname-YYYY-MM-DD--HH.MM.tgz
# Download via SCP or datastore browser
# Alternative — collect specific logs:
esxcli system syslog config get
cat /var/log/vmkernel.log | grep -i "error\|warn\|scsi\|nmp" | tail -50
cat /var/log/hostd.log | grep -i "error\|fail" | tail -30
Collect vCenter support bundle
# Via vSphere Client UI:
# Menu → Administration → Support → Export System Logs
# Select vCenter + relevant hosts → Generate bundle
# Via VCSA CLI:
vc-support.sh
# Via VAMI:
# https://vcsa:5480 → Actions → Create Support Bundle
# Output: /storage/log/vmware/support/vc-support-bundle-*.tgz
Quick log analysis — find errors fast
# Search across all vCenter logs for errors in last hour:
find /var/log/vmware/ -name "*.log" -mmin -60 -exec \
grep -l "ERROR\|CRITICAL\|Exception" {} \;
# vpxd.log — check for task failures:
grep "Task\|error\|warn" /var/log/vmware/vpxd/vpxd.log | tail -50
# Timeline correlation — find events around a specific time:
grep "2026-05-17T0[2-3]:" /var/log/vmware/vpxd/vpxd.log | head -50
Enable/disable SSH and configure timeouts
# Enable SSH (temporary for troubleshooting):
vim-cmd hostsvc/enable_ssh
# Disable SSH when done:
vim-cmd hostsvc/disable_ssh
# Set ESXi Shell idle timeout (900 seconds = 15 min):
esxcli system settings advanced set -o /UserVars/ESXiShellTimeOut -i 900
# Set SSH interactive timeout:
esxcli system settings advanced set -o /UserVars/ESXiShellInteractiveTimeOut -i 900
# Suppress shell warning (optional — not recommended for production):
esxcli system settings advanced set -o /UserVars/SuppressShellWarning -i 1
Configure account lockout and password policies
# Set account lockout after 5 failed attempts:
esxcli system settings advanced set -o /Security/AccountLockFailures -i 5
# Set lockout duration (900 seconds = 15 min):
esxcli system settings advanced set -o /Security/AccountUnlockTime -i 900
# Set password complexity requirements:
esxcli system settings advanced set -o /Security/PasswordQualityControl \
-s "retry=3 min=disabled,disabled,disabled,7,7"
# Verify current settings:
esxcli system settings advanced list -o /Security/AccountLockFailures
esxcli system settings advanced list -o /UserVars/ESXiShellTimeOut
Enable lockdown mode (production environments)
# Enable lockdown mode via DCUI or vSphere Client:
# Host → Configure → System → Security Profile → Lockdown Mode
# Options: Normal (API access via vCenter only) or Strict (no DCUI)
# PowerCLI — enable normal lockdown:
(Get-VMHost "esxi01.domain.local").ExtensionData.EnterLockdownMode()
# Add exception users (for monitoring/backup agents):
# Host → Configure → System → Security Profile → Lockdown Mode → Exception Users
# Add: svc-monitoring@domain.local
# Verify lockdown status:
(Get-VMHost "esxi01.domain.local").ExtensionData.Config.LockdownMode
LDAP bind failed or connection refusedvCenter SSO authenticates AD/LDAP users by binding to a domain controller using a service account. When that bind password expires (common with 90-day AD password policies), or when the DC becomes unreachable due to DNS or firewall changes, all domain users are locked out. Only the local administrator@vsphere.local account remains functional. LDAPS configurations are also fragile — if the DC's SSL certificate changes or expires, the trust chain breaks.
Check SSO identity source configuration and connectivity
# SSH to VCSA — check LookupService location:
/usr/lib/vmware-vmafd/bin/vmafd-cli get-ls-location --server-name localhost
# Test LDAP connectivity from VCSA:
ldapsearch -H ldap://dc01.domain.local:389 \
-D "CN=svc-vcenter,OU=Service Accounts,DC=domain,DC=local" \
-w 'BindPassword' -b "DC=domain,DC=local" "(sAMAccountName=testuser)"
# Test LDAPS connectivity:
openssl s_client -connect dc01.domain.local:636 -showcerts &1 | \
openssl x509 -noout -dates -subject
# Check DNS resolution for AD domain:
nslookup domain.local
nslookup dc01.domain.local
Review SSO logs for authentication errors
# Check SSO admin server log:
grep -i "ldap\|bind\|identity\|error\|fail" \
/var/log/vmware/sso/ssoAdminServer.log | tail -30
# Check VMware Directory Service:
grep -i "error\|ldap" /var/log/vmware/vmdir/vmdird-syslog.log | tail -20
# Check VMAFD service:
/usr/lib/vmware-vmafd/bin/vmafd-cli get-status --server-name localhost
Update identity source bind password
# Log in as administrator@vsphere.local:
# vSphere Client → Administration → Single Sign-On → Configuration
# → Identity Sources tab → Select the AD/LDAP source → Edit
# Update the bind account password
# Click "Test Connection" to verify
# Save changes
# If UI is inaccessible, use sso-config CLI:
/opt/vmware/bin/sso-config.sh -set_identity_source \
-type adOverLdap \
-domain domain.local \
-alias DOMAIN \
-servicePrincipalName "svc-vcenter@domain.local" \
-servicePassword "NewPassword" \
-primaryUrl "ldaps://dc01.domain.local:636"
Update LDAPS certificate trust (if certificate changed)
# Export DC certificate:
openssl s_client -connect dc01.domain.local:636 &1 | \
sed -n '/BEGIN CERTIFICATE/,/END CERTIFICATE/p' > /tmp/dc-cert.pem
# Add to VCSA trusted certs:
/usr/lib/vmware-vmafd/bin/dir-cli trustedcert publish \
--cert /tmp/dc-cert.pem \
--login administrator@vsphere.local
# Restart SSO-related services:
service-control --stop vmware-stsd vmware-sts-idmd
service-control --start vmware-stsd vmware-sts-idmd
All vSphere components rely on accurate, synchronized time. ESXi hosts, VCSA, and VMs must agree on the current time within a tight tolerance. Kerberos authentication fails with >5 minutes of drift. Certificate validation uses timestamps for validity checks — a clock set 2 years ahead can invalidate certificates. HA heartbeats rely on time correlation — significant drift causes false isolation events. The problem compounds because time drift is gradual and often unnoticed until it causes cascading failures.
Check time and NTP status on ESXi and VCSA
# ESXi — check current time and NTP config:
date
esxcli system ntp get
esxcli system ntp config get
# Check NTP service status:
/etc/init.d/ntpd status
# VCSA — check time and chrony status:
# SSH to VCSA:
timedatectl
chronyc tracking
chronyc sources -v
Compare time across all hosts
# PowerCLI — check time on all hosts in cluster:
Get-Cluster "ClusterName" | Get-VMHost | ForEach-Object {
$hostTime = (Get-View $_.ExtensionData.ConfigManager.DateTimeSystem).QueryDateTime()
[PSCustomObject]@{
Host = $_.Name
HostTime = $hostTime
Drift = ($hostTime - (Get-Date)).TotalSeconds
}
} | Format-Table -AutoSize
# Check NTP config on all hosts:
Get-Cluster "ClusterName" | Get-VMHost | ForEach-Object {
$ntp = Get-VMHostNtpServer -VMHost $_
[PSCustomObject]@{ Host = $_.Name; NTPServers = ($ntp -join ", ") }
} | Format-Table -AutoSize
Configure NTP on ESXi hosts
# Set NTP servers:
esxcli system ntp set --server=ntp1.domain.local --server=ntp2.domain.local
# Enable and start NTP:
esxcli system ntp set --enabled=true
/etc/init.d/ntpd restart
# Verify NTP is syncing:
esxcli system ntp get
# Expected: "Running: true" and servers showing sync status
# PowerCLI — configure NTP on all hosts in cluster:
Get-Cluster "ClusterName" | Get-VMHost | ForEach-Object {
Add-VMHostNtpServer -VMHost $_ -NtpServer "ntp1.domain.local","ntp2.domain.local"
Get-VMHostService -VMHost $_ | Where { $_.Key -eq "ntpd" } | Start-VMHostService -Confirm:$false
Get-VMHostService -VMHost $_ | Where { $_.Key -eq "ntpd" } | Set-VMHostService -Policy "on"
}
Configure NTP on VCSA
# VCSA — configure NTP via VAMI:
# https://vcsa:5480 → Time → Edit → Time Synchronization Mode: NTP
# NTP Servers: ntp1.domain.local, ntp2.domain.local
# Or via CLI:
/opt/vmware/bin/timesync.sh ntp ntp1.domain.local ntp2.domain.local
# Verify chrony status:
chronyc tracking
# Check "System time" offset — should be < 1 second
# Force immediate sync if drift is large:
chronyc makestep
Configure remote syslog on ESXi hosts
# Set remote syslog target (UDP):
esxcli system syslog config set --loghost=udp://syslog.domain.local:514
# For reliable delivery, use TCP:
esxcli system syslog config set --loghost=tcp://syslog.domain.local:514
# For encrypted transport, use SSL:
esxcli system syslog config set --loghost=ssl://syslog.domain.local:6514
# Multiple targets (comma-separated):
esxcli system syslog config set \
--loghost=tcp://syslog.domain.local:514,tcp://siem.domain.local:514
# Reload syslog daemon:
esxcli system syslog reload
Verify syslog configuration and test delivery
# Verify current syslog config:
esxcli system syslog config get
# Open firewall for syslog:
esxcli network firewall ruleset set -r syslog -e true
# Send test syslog message:
esxcli system syslog mark --message="Test syslog from $(hostname)"
# Verify on remote syslog server:
# grep "Test syslog" /var/log/remote/esxi*.log
# PowerCLI — configure syslog on all hosts:
Get-Cluster "ClusterName" | Get-VMHost | ForEach-Object {
Set-VMHostSysLogServer -VMHost $_ -SysLogServer "tcp://syslog.domain.local:514"
$_ | Get-VMHostFirewallException | Where { $_.Name -eq "syslog" } | Set-VMHostFirewallException -Enabled $true
}
Configure VCSA syslog forwarding
# Via VAMI:
# https://vcsa:5480 → Syslog → Configure
# Protocol: TCP or TLS
# Server: syslog.domain.local
# Port: 514 (TCP) or 6514 (TLS)
# Via CLI on VCSA:
# Edit rsyslog config:
cat >> /etc/rsyslog.d/vmware-services.conf << 'EOF'
*.* @@syslog.domain.local:514
EOF
systemctl restart rsyslog
# Verify forwarding:
logger -t vcsa-test "Syslog forwarding test from VCSA"
Host Profiles capture the configuration of a reference host (NTP, networking, storage, security, services) and enforce that configuration across all hosts in a cluster. When a host deviates from the profile (drift), a compliance check flags it as non-compliant. Remediation puts the host in maintenance mode and applies the profile. Answer files provide host-specific values (IP addresses, hostnames) that differ per host.
Extract host profile from reference host
# vSphere Client:
# Menu → Policies and Profiles → Host Profiles
# → Extract Profile from a Host
# Select reference host → Name the profile → Finish
# PowerCLI — extract host profile:
$refHost = Get-VMHost "esxi-ref01.domain.local"
New-VMHostProfile -Name "Production-Cluster-Profile" \
-ReferenceHost $refHost -Description "Extracted $(Get-Date -Format yyyy-MM-dd)"
# Review profile settings:
$profile = Get-VMHostProfile -Name "Production-Cluster-Profile"
$profile | Get-VMHostProfileRequiredInput
Attach profile and check compliance
# Attach profile to cluster:
# Host Profiles → Select profile → Attach/Detach Hosts and Clusters
# Select target cluster → Attach
# PowerCLI — attach and check compliance:
$cluster = Get-Cluster "Production-Cluster"
$profile = Get-VMHostProfile "Production-Cluster-Profile"
Apply-VMHostProfile -Profile $profile -Entity $cluster -AssociateOnly -Confirm:$false
# Check compliance:
Test-VMHostProfileCompliance -VMHost (Get-Cluster "Production-Cluster" | Get-VMHost) |
Select VMHost, ComplianceStatus, IncomplianceElementList |
Format-Table -AutoSize
Configure answer files and remediate
# Pre-populate answer files (host-specific values):
# Host Profiles → Select profile → Edit Host Customizations
# Set per-host values: management IP, hostname, etc.
# Remediate non-compliant hosts:
# Right-click non-compliant host → Host Profiles → Remediate
# Host enters maintenance mode → profile applied → host reboots
# PowerCLI — remediate host:
$vmhost = Get-VMHost "esxi02.domain.local"
Set-VMHost -VMHost $vmhost -State "Maintenance" -Confirm:$false
Apply-VMHostProfile -Profile $profile -Entity $vmhost -Confirm:$false
Set-VMHost -VMHost $vmhost -State "Connected" -Confirm:$false
# Verify compliance after remediation:
Test-VMHostProfileCompliance -VMHost $vmhost | Select ComplianceStatus
esxtop is the definitive tool for real-time ESXi performance troubleshooting. Understanding key counters like %RDY, KAVG, and SWPRT is essential for diagnosing VM slowness, storage latency, and resource contention at the hypervisor level.
Real-time monitoring with esxtop
# SSH to ESXi host and launch esxtop:
esxtop
# Navigation keys:
# c = CPU view m = Memory view
# n = Network view d = Disk/Storage view
# u = Disk device v = VM disk (virtual)
# p = Power i = Interrupt
# Useful key commands inside esxtop:
# f = Toggle fields (add/remove counters)
# o = Order/sort by column
# V = Toggle VM-only view
# s = Set refresh interval (default 5s)
# Filter to specific VM:
# Press 'f' to add fields, then 'V' for VM-only mode
Batch mode for data collection and analysis
# Capture 60 samples at 5-second intervals to CSV:
esxtop -b -d 5 -n 60 > /tmp/perfdata.csv
# Capture with specific counters (use .esxtop-rc config):
# Create custom config: run esxtop → configure fields → press W to save
# Then use saved config in batch mode:
esxtop -b -d 5 -n 120 -c /etc/esxtop-custom.rc > /tmp/perfdata.csv
# Download CSV via SCP for analysis:
# scp root@esxi01:/tmp/perfdata.csv ./
# Open in Windows Performance Monitor (perfmon):
# Import CSV → analyze trends, spikes, and correlations
# Quick CLI analysis — find peak CPU ready:
awk -F',' 'NR>1 {print $1, $5}' /tmp/perfdata.csv | sort -t',' -k2 -rn | head
VM-level I/O profiling with vscsiStats
# List VMs with world IDs:
vscsiStats -l
# Start I/O profiling for a specific VM (by world ID):
vscsiStats -s -w <worldID>
# Collect histogram data (run during workload):
vscsiStats -p all -w <worldID>
# Save results and stop profiling:
vscsiStats -p all -w <worldID> > /tmp/vm-io-profile.txt
vscsiStats -x -w <worldID>
# Key output: I/O size distribution, latency histogram
# Helps identify: random vs sequential I/O, read/write ratio, latency buckets