When an Edge Transport Node (TN) is deleted while in Maintenance Mode, the IP addresses (TEP IPs) may not be released back to the IP pool. This leads to IP address exhaustion within the pool, potentially preventing the configuration of new Edge TNs or other resources.
In /var/log/proton/nsxapi.log, logs similar to the following may be observed:
YYYY-MM-DDT HH:MM:SS INFO L2HostConfigTaskExecutor# TransportNodeAsyncServiceImpl #### FABRIC [nsx@6876 comp="nsx-manager" level="INFO" subcomp="manager"] VTEP Resources To be released and TN State To Be Deleted for TN <UUID>, failure com.vmware.nsx.management.switching.common.exceptions.SwitchingException: Communication with the host <UUID> failed. Error: MessagingException, isForceDelete true
YYYY-MM-DDT HH:MM:SS INFO L2HostConfigTaskExecutor# TransportNodeAsyncServiceImpl #### FABRIC [nsx@6876 comp="nsx-manager" level="INFO" subcomp="manager"] TransportNodeState of TransportNode/<UUID> deleted after the TransportNode configuration deletion.
VMware NSX
The issue is caused by a race condition in the Edge Transport Node deletion state machine. When an Edge is in Maintenance Mode, the isForceDelete flag is set to True. If an RPC Error occurs during the WAITING_HOST_CONFIG_REPLY_MSG phase, the error handler incorrectly sets the HostSwitchVtepResourceMap to null in the execution context.
Because this map is required to identify and release the allocated IP addresses, the system silently skips the IP de-allocation logic during the final PERSISTING_TNSTATE stage, even though the Edge TN object is successfully deleted.
This issue has already been addressed in NSX 9.0.
Workaround: If the issue has already occurred and IP addresses are leaked, manually release the stale IP addresses from the IP pool using the NSX API:
Identify the IP Pool ID and the stale Allocation ID:
GET https://<NSX-Manager-IP>/api/v1/pools/ip-pools/
GET https://<NSX-Manager-IP>/api/v1/pools/ip-pools/<IP-Pool-ID>/allocations
Manually release the affected IP address:
POST https://<NSX-Manager-IP>/api/v1/pools/ip-pools/<IP-Pool-ID>?action=RELEASE
{
"allocation_id": "<Stale-IP-Address>"
}