Repository: kubernetes/kubernetes (language: go)

Issue:
[Windows] HNS endpoints creation fails after remote HNS endpoints with same IP address were created
### What happened?

When deploying Windows containers on Windows Nodes, some Windows containers fails to have network configuration inside like this:
```
S C:\> ipconfig /all

Windows IP Configuration

   Host Name . . . . . . . . . . . . : windows-server-iis-ltsc2022-58467d4759-vgzjr
   Primary Dns Suffix  . . . . . . . : 
   Node Type . . . . . . . . . . . . : Hybrid
   IP Routing Enabled. . . . . . . . : No
   WINS Proxy Enabled. . . . . . . . : No
```

This issue happens for Windows containers that got assigned the same IP address that was previously assigned to pods on Linux but were deleted later.

When we create a Pod on Linux and a `LoadBalancer` service type that refers to Linux pod, `kube-proxy` on Windows create HNS endpoints of Remote type. If we delete these Linux pods, IP addresses assigned to these pods are released and Remote HNS endpoints are deleted from Windows nodes.

When I deploy Windows pod, and if this Windows pod gets assigned the same IP as Linux pod, HNS endpoint for these Windows containers fails to be created causing networking issues inside Windows container.

This issue is a likely regression due to #124092

### What did you expect to happen?

All Windows containers should successfully create HNS endpoint and networking should work inside Windows containers.

### How can we reproduce it (as minimally and precisely as possible)?

1. Deploy kubernetes cluster with limited available IPs for pods on both Linux and Windows node.
2. Deploy Linux pods that consume almost all IPs.
3. Deploy service type LoadBalancer that refer to Linux pods, This will trigger `kube-proxy` to create Remote HNS endpoint on Windows. This Remote HNS endpoint will have Linux pod IP.
4. Scale down the Linux pods to 1.
5. Deploy Windows pods so that same IP address from Linux pod can be reassigned to Windows Pods.
6. HNS endpoints for Windows pods with same address will not be created.
7. Internet connectivity inside these Windows pod will fail.

### Anything else we need to know?

_No response_

### Kubernetes version

<details>

```console
$ kubectl version
1.31 and higher only
```

</details>


### Cloud provider

<details>
EKS
</details>


### OS version

<details>

```console
# On Linux:
$ cat /etc/os-release
# paste output here
$ uname -a
# paste output here

# On Windows:
C:\> wmic os get Caption, Version, BuildNumber, OSArchitecture

BuildNumber  Caption                                   OSArchitecture  Version
20348        Microsoft Windows Server 2022 Datacenter  64-bit          10.0.20348
```

</details>


### Install tools

<details>

</details>


### Container runtime (CRI) and version (if applicable)

<details>

</details>


### Related plugins (CNI, CSI, ...) and versions (if applicable)

<details>

</details>



Discussion / hints:
This issue is currently awaiting triage.

If a SIG or subproject determines this is a relevant issue, they will accept it by applying the `triage/accepted` label and provide further guidance.

The `triage/accepted` label can be added by org members by writing `/triage accepted` in a comment.


<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes-sigs/prow](https://github.com/kubernetes-sigs/prow/issues/new?title=Prow%20issue:) repository.
</details>
/windows

/sig windows
@princepereira @sbangari have you seen any reports of this?  

> When I deploy Windows pods, and if these Windows pods get assigned the same IP as Linux pod, HNS endpoint for these Windows containers fails to be created causing networking issues inside Windows containers.

When you say windows pods get assigned the same IP as linux pod, you mean the deleted ones?  Pods should not get the same ip as other pods.

What CNI is involved?
>When you say windows pods get assigned the same IP as linux pod, you mean the deleted ones? Pods should not get the same ip as other pods.

Yes, I mean Windows pods getting same IP as deleted Linux Pods. I am using [AWS CNI](https://github.com/aws/amazon-vpc-cni-plugins/tree/master/plugins/vpc-bridge) plugin. I don't think this issue is related to CNI plugin. We don't see this issue prior to `1.31` with same CNI plugin.

/assign @princepereira 
@jsturtevant , @KlwntSingh , I will begin investigating this issue.

@KlwntSingh , Do you have relevant kubeproxy logs and problem ip to share.
We did some initial investigation in slack https://kubernetes.slack.com/archives/C0SJ4AFB7/p1743016356145739

Looks very suspiciously  https://github.com/kubernetes/kubernetes/pull/113521 and https://github.com/kubernetes/kubernetes/issues/113524. And the same code around endpoint hash was moved around.  
Hi @princepereira ,
I am attaching `kube-proxy` logs. I enabled debug logs with `-v=5` flag to `kube-proxy`. Hope it helps. Do let me know if you need any other logs.

The problematic IP in this repro has `192.168.0.13` IP and Windows pod were deployed after `Friday, March 28, 2025 5:34:29 AM` time on Windows worker node.

[kube-proxy.csv](https://github.com/user-attachments/files/19499544/kube-proxy.csv)
> Hi [@princepereira](https://github.com/princepereira) , I am attaching `kube-proxy` logs. I enabled debug logs with `-v=5` flag to `kube-proxy`. Hope it helps. Do let me know if you need any other logs.
> 
> The problematic IP in this repro has `192.168.0.13` IP and Windows pod were deployed after `Friday, March 28, 2025 5:34:29 AM` time on Windows worker node.
> 
> [kube-proxy.csv](https://github.com/user-attachments/files/19499544/kube-proxy.csv)

@KlwntSingh ,
Thanks for the logs! I'm starting on it now. And really appreciate your hep in changing the log level :). If you have the endpoint guid of 192.168.0.13, please share that as well. Is this pod part of multiple services or a single service?

I also attempted to reproduce the issue locally with Linux pods using the scaling sequences 0->10->0, 0->20->0, and 0->30->0. However, I was unable to replicate the problem. After scaling back to 0, all remote endpoints cleared as expected. I didn’t use a shorter range for pod IPs.

How frequently are you able to reproduce this issue, and how difficult is it? Have you tried similar reproduction steps in Kubernetes 1.30 or earlier versions?

As per the logs shared,

There are 12 remote endpoints as part of old endpoint map which also includes "192.168.0.13"

```
I0328 05:34:50.465299    4172 proxier.go:177] "endpointsMapChange oldEndpointsMap" svcPortName="default/nginx-service-loadbalancer" endpoints=<
"	"
"	  192.168.0.10:80={Ready:false,Serving:true,Terminating:true,IsRemote:true}"
"	  192.168.0.13:80={Ready:false,Serving:true,Terminating:true,IsRemote:true}"
"	  192.168.0.15:80={Ready:false,Serving:true,Terminating:true,IsRemote:true}"
"	  192.168.0.19:80={Ready:false,Serving:true,Terminating:true,IsRemote:true}"
"	  192.168.0.20:80={Ready:false,Serving:true,Terminating:true,IsRemote:true}"
"	  192.168.0.22:80={Ready:false,Serving:true,Terminating:true,IsRemote:true}"
"	  192.168.0.25:80={Ready:false,Serving:true,Terminating:true,IsRemote:true}"
"	  192.168.0.26:80={Ready:false,Serving:true,Terminating:true,IsRemote:true}"
"	  192.168.0.30:80={Ready:true,Serving:true,Terminating:false,IsRemote:true}"
"	  192.168.0.5:80={Ready:false,Serving:true,Terminating:true,IsRemote:true}"
"	  192.168.0.7:80={Ready:false,Serving:true,Terminating:true,IsRemote:true}"
"	  192.168.0.9:80={Ready:false,Serving:true,Terminating:true,IsRemote:true}"
 >
```

out of which 1 remote endpoint is still part of new endpoint map.

```
I0328 05:34:50.465299    4172 proxier.go:177] "endpointsMapChange newEndpointsMap" svcPortName="default/nginx-service-loadbalancer" endpoints=<
"	"
"	  192.168.0.30:80={Ready:true,Serving:true,Terminating:false,IsRemote:true}"
 >
```

So, I am expecting 11 endpoint deletion which I can see here.

```
I0328 05:34:50.475466    4172 proxier.go:1729] "Deleting unreferenced remote endpoint" hnsID="9f9c5813-47bf-452f-97c4-4d13f8db688d"
I0328 05:34:50.476092    4172 hns.go:298] "Remote endpoint resource deleted" hnsID="9f9c5813-47bf-452f-97c4-4d13f8db688d"
I0328 05:34:50.476092    4172 proxier.go:1729] "Deleting unreferenced remote endpoint" hnsID="01ae1519-1112-455f-a0be-04f16d88a1c9"
I0328 05:34:50.476661    4172 hns.go:298] "Remote endpoint resource deleted" hnsID="01ae1519-1112-455f-a0be-04f16d88a1c9"
I0328 05:34:50.479519    4172 proxier.go:1729] "Deleting unreferenced remote endpoint" hnsID="40424f52-e3c9-4835-8360-6dd029762be2"
I0328 05:34:50.480095    4172 hns.go:298] "Remote endpoint resource deleted" hnsID="40424f52-e3c9-4835-8360-6dd029762be2"
I0328 05:34:50.480095    4172 proxier.go:1729] "Deleting unreferenced remote endpoint" hnsID="1281cade-044b-4ef4-bb0a-cfc2ba788c09"
I0328 05:34:50.480952    4172 hns.go:298] "Remote endpoint resource deleted" hnsID="1281cade-044b-4ef4-bb0a-cfc2ba788c09"
I0328 05:34:50.480989    4172 proxier.go:1729] "Deleting unreferenced remote endpoint" hnsID="8938ea0c-f645-402a-8eb3-a6b9d90c9bd9"
I0328 05:34:50.481034    4172 hns.go:298] "Remote endpoint resource deleted" hnsID="8938ea0c-f645-402a-8eb3-a6b9d90c9bd9"
I0328 05:34:50.481034    4172 proxier.go:1729] "Deleting unreferenced remote endpoint" hnsID="fc26ef22-dfe1-40d0-bc6b-1dbb5436de3b"
I0328 05:34:50.481646    4172 hns.go:298] "Remote endpoint resource deleted" hnsID="fc26ef22-dfe1-40d0-bc6b-1dbb5436de3b"
I0328 05:34:50.481646    4172 proxier.go:1729] "Deleting unreferenced remote endpoint" hnsID="6b0ef218-7772-43a1-8d78-5b6b9541eed8"
I0328 05:34:50.482343    4172 hns.go:298] "Remote endpoint resource deleted" hnsID="6b0ef218-7772-43a1-8d78-5b6b9541eed8"
I0328 05:34:50.482343    4172 proxier.go:1729] "Deleting unreferenced remote endpoint" hnsID="991de03a-1aa3-456b-9dc0-d8cc3ea4d837"
I0328 05:34:50.483213    4172 hns.go:298] "Remote endpoint resource deleted" hnsID="991de03a-1aa3-456b-9dc0-d8cc3ea4d837"
I0328 05:34:50.483213    4172 proxier.go:1729] "Deleting unreferenced remote endpoint" hnsID="3e102950-d0c5-40ed-8916-af7af587863b"
I0328 05:34:50.483825    4172 hns.go:298] "Remote endpoint resource deleted" hnsID="3e102950-d0c5-40ed-8916-af7af587863b"
I0328 05:34:50.483825    4172 proxier.go:1729] "Deleting unreferenced remote endpoint" hnsID="fc6564e4-6dab-4c98-acee-3f3ab4b9544e"
I0328 05:34:50.484008    4172 hns.go:298] "Remote endpoint resource deleted" hnsID="fc6564e4-6dab-4c98-acee-3f3ab4b9544e"
I0328 05:34:50.485214    4172 proxier.go:1729] "Deleting unreferenced remote endpoint" hnsID="04d7ae63-ed28-46c6-8f61-1c2bfed1afca"
I0328 05:34:50.485813    4172 hns.go:298] "Remote endpoint resource deleted" hnsID="04d7ae63-ed28-46c6-8f61-1c2bfed1afca"
```
Hi @princepereira , Thanks for taking a look.
>If you have the endpoint guid of 192.168.0.13, please share that as well. Is this pod part of multiple services or a single service?

Yeah, this is the issue. HNS endpoint with IP `192.168.0.13` doesn't get created again.

>I also attempted to reproduce the issue locally with Linux pods using the scaling sequences 0->10->0, 0->20->0, and 0->30->0. However, I was unable to replicate the problem. After scaling back to 0, all remote endpoints cleared as expected. I didn’t use a shorter range for pod IPs.

I am able to reproduce the issue persistently, It is easy to repro. After scalling down Linux pod, Please launch Windows pod because HNS endpoint for Windows pod with same IP as Linux won't get created.

>Have you tried similar reproduction steps in Kubernetes 1.30 or earlier versions?

We don't have this issue in 1.30 at all. It only started with 1.31.
Hi @princepereira , I found Endpoint ID for Windows Pod with same IP from our CNI logs. It is `903b10f3-d93f-4b26-aa76-e28d60401298`.

I see `kube-proxy` deleted this endpoint little shortly after it was created.

```
b4bb3bcc-35c2-46c0-9380-fd45db0f420a"":{},""ca7649a8-3c58-4f15-b7c7-6ef2de4c1e70"":{}}"
"I0328 05:35:32.181970    4172 hns.go:342] ""Queried load balancers"" count=7"
"I0328 05:35:32.181970    4172 proxier.go:1209] ""Syncing Policies"""
"I0328 05:35:32.181970    4172 proxier.go:1144] ""Syncing proxy rules complete"" elapsed=""7.201ms"""
"I0328 05:35:32.181970    4172 bounded_frequency_runner.go:296] sync-runner: ran, next possible in 1s, periodic in 30s"
"I0328 05:35:50.500343    4172 hns.go:171] ""Queried endpoints from network"" network=""vpcbr064a46fb8f7b"""
"I0328 05:35:50.500343    4172 hns.go:172] ""Queried endpoints details"" network=""vpcbr064a46fb8f7b"" endpointInfos={""172.0.32.0"":{},""192.168.0.11"":{},""192.168.0.12"":{},""192.168.0.13"":{},""192.168.0.14"":{},""192.168.0.18"":{},""192.168.0.21"":{},""192.168.0.28"":{},""192.168.0.29"":{},""192.168.0.30"":{},""192.168.0.4"":{},""192.168.0.49"":{},""192.168.0.6"":{},""192.168.0.8"":{},""192.168.0.9"":{},""2f366b7b-2ed6-449b-9476-ed4675fd7754"":{},""3744ccc0-666a-4d1e-ae72-3c4361bf6b49"":{},""3846bdd4-f738-4504-b2d7-80483631fd64"":{},""5895c4f1-25fc-4fbe-b1f9-896278ac4862"":{},""5dd74779-47d9-43a6-9040-3036d1554fa6"":{},""6aa1c8f3-2aad-4fa0-a897-d6dbe9376b85"":{},""7547b634-c1b7-4b05-bfc7-acb732bf25de"":{},""76bd12f2-2815-4c5e-b420-f8847116e65a"":{},""776418ee-c819-4417-9500-6f9f90b6f5ef"":{},""84e356ca-280d-4ddc-90ba-20eaf2cdaf6e"":{},""903b10f3-d93f-4b26-aa76-e28d60401298"":{},""9acf0324-0b5e-4dcd-810a-599b1ab4fcf2"":{},""a7fa2528-a371-4dd2-bb0a-a030274aad49"":{},""b4bb3bcc-35c2-46c0-9380-fd45db0f420a"":{},""ca7649a8-3c58-4f15-b7c7-6ef2de4c1e70"":{}}"
"I0328 05:35:50.502070    4172 hns.go:342] ""Queried load balancers"" count=7"
"I0328 05:35:50.502070    4172 proxier.go:1209] ""Syncing Policies"""
"I0328 05:35:50.502070    4172 proxier.go:1220] ""Policy already applied"" serviceInfo=""10.100.0.10:53/TCP"""
"I0328 05:35:50.502070    4172 proxier.go:1220] ""Policy already applied"" serviceInfo=""10.100.0.10:9153/TCP"""
"I0328 05:35:50.502070    4172 proxier.go:1220] ""Policy already applied"" serviceInfo=""10.100.0.10:53/UDP"""
"I0328 05:35:50.502070    4172 proxier.go:1220] ""Policy already applied"" serviceInfo=""10.100.0.1:443/TCP"""
"I0328 05:35:50.502070    4172 proxier.go:1220] ""Policy already applied"" serviceInfo=""10.100.23.169:80/TCP"""
"I0328 05:35:50.502070    4172 proxier.go:1220] ""Policy already applied"" serviceInfo=""10.100.10.220:443/TCP"""
"I0328 05:35:50.502070    4172 proxier.go:1729] ""Deleting unreferenced remote endpoint"" hnsID=""903b10f3-d93f-4b26-aa76-e28d60401298"""
"I0328 05:35:50.587637    4172 hns.go:298] ""Remote endpoint resource deleted"" hnsID=""903b10f3-d93f-4b26-aa76-e28d60401298"""
"I0328 05:35:50.597916    4172 proxier.go:1729] ""Deleting unreferenced remote endpoint"" hnsID=""776418ee-c819-4417-9500-6f9f90b6f5ef"""
"I0328 05:35:50.681628    4172 hns.go:298] ""Remote endpoint resource deleted"" hnsID=""776418ee-c819-4417-9500-6f9f90b6f5ef"""
"I0328 05:35:50.688167    4172 proxier.go:1144] ""Syncing proxy rules complete"" elapsed=""196.0246ms"""
"I0328 05:35:50.688167    4172 bounded_frequency_runner.go:296] sync-runner: ran, next possible in 1s, periodic in 30s"
"I0328 05:36:02.189150    4172 hns.go:171] ""Queried endpoints from network"" network=""vpcbr064a46fb8f7b"""
```
Hi @princepereira , As requested on slack, complete `kube-proxy` logs can be found [here](https://github.com/kubernetes/kubernetes/issues/130963#issuecomment-2760253318).

I am attaching corresponding CNI logs - [vpc-bridge.txt](https://github.com/user-attachments/files/19537901/vpc-bridge.txt)

Fix patch:
diff --git a/pkg/proxy/winkernel/hns.go b/pkg/proxy/winkernel/hns.go
index 13f1ea868fb5a..d6e425f8b77b8 100644
--- a/pkg/proxy/winkernel/hns.go
+++ b/pkg/proxy/winkernel/hns.go
@@ -133,40 +133,43 @@ func (hns hns) getAllEndpointsByNetwork(networkName string) (map[string]*(endpoi
 			continue
 		}
 
-		// Add to map with key endpoint ID or IP address
-		// Storing this is expensive in terms of memory, however there is a bug in Windows Server 2019 that can cause two endpoints to be created with the same IP address.
-		// TODO: Store by IP only and remove any lookups by endpoint ID.
-		endpointInfos[ep.Id] = &endpointInfo{
-			ip:         ep.IpConfigurations[0].IpAddress,
-			isLocal:    uint32(ep.Flags&hcn.EndpointFlagsRemoteEndpoint) == 0,
-			macAddress: ep.MacAddress,
-			hnsID:      ep.Id,
-			hns:        hns,
-			// only ready and not terminating endpoints were added to HNS
-			ready:       true,
-			serving:     true,
-			terminating: false,
-		}
-		endpointInfos[ep.IpConfigurations[0].IpAddress] = endpointInfos[ep.Id]
+		for index, ipConfig := range ep.IpConfigurations {
+
+			if index > 1 {
+				// Expecting only ipv4 and ipv6 ipaddresses
+				// This is highly unlikely to happen, but if it does, we should log a warning
+				// and break out of the loop
+				klog.Warning("Endpoint ipconfiguration holds more than 2 IP addresses.", "hnsID", ep.Id, "IP", ipConfig.IpAddress, "ipConfigCount", len(ep.IpConfigurations))
+				break
+			}
 
-		if len(ep.IpConfigurations) == 1 {
-			continue
-		}
+			isLocal := uint32(ep.Flags&hcn.EndpointFlagsRemoteEndpoint) == 0
 
-		// If ipFamilyPolicy is RequireDualStack or PreferDualStack, then there will be 2 IPS (iPV4 and IPV6)
-		// in the endpoint list
-		endpointDualstack := &endpointInfo{
-			ip:         ep.IpConfigurations[1].IpAddress,
-			isLocal:    uint32(ep.Flags&hcn.EndpointFlagsRemoteEndpoint) == 0,
-			macAddress: ep.MacAddress,
-			hnsID:      ep.Id,
-			hns:        hns,
-			// only ready and not terminating endpoints were added to HNS
-			ready:       true,
-			serving:     true,
-			terminating: false,
+			if existingEp, ok := endpointInfos[ipConfig.IpAddress]; ok && isLocal {
+				// If the endpoint is already part of the queried endpoints map and is local,
+				// then we should not add it again to the map
+				// This is to avoid overwriting the remote endpoint info with a local endpoint.
+				klog.V(3).InfoS("Endpoint already exists in queried endpoints map; skipping.", "newLocalEndpoint", ep, "ipConfig", ipConfig, "existingEndpoint", existingEp)
+				continue
+			}
+
+			// Add to map with key endpoint ID or IP address
+			// Storing this is expensive in terms of memory, however there is a bug in Windows Server 2019 and 2022 that can cause two endpoints (local and remote) to be created with the same IP address.
+			// TODO: Store by IP only and remove any lookups by endpoint ID.
+			epInfo := &endpointInfo{
+				ip:         ipConfig.IpAddress,
+				isLocal:    isLocal,
+				macAddress: ep.MacAddress,
+				hnsID:      ep.Id,
+				hns:        hns,
+				// only ready and not terminating endpoints were added to HNS
+				ready:       true,
+				serving:     true,
+				terminating: false,
+			}
+			endpointInfos[ep.Id] = epInfo
+			endpointInfos[ipConfig.IpAddress] = epInfo
 		}
-		endpointInfos[ep.IpConfigurations[1].IpAddress] = endpointDualstack
 	}
 	klog.V(3).InfoS("Queried endpoints from network", "network", networkName, "count", len(endpointInfos))
 	klog.V(5).InfoS("Queried endpoints details", "network", networkName, "endpointInfos", endpointInfos)
diff --git a/pkg/proxy/winkernel/proxier.go b/pkg/proxy/winkernel/proxier.go
index d35049642006a..91fb6fad8d40b 100644
--- a/pkg/proxy/winkernel/proxier.go
+++ b/pkg/proxy/winkernel/proxier.go
@@ -535,6 +535,11 @@ func (ep *endpointInfo) DecrementRefCount() {
 	if !ep.IsLocal() && ep.refCount != nil && *ep.refCount > 0 {
 		*ep.refCount--
 	}
+	refCount := 0
+	if ep.refCount != nil {
+		refCount = int(*ep.refCount)
+	}
+	klog.V(5).InfoS("Endpoint RefCount after decrement.", "endpointInfo", ep, "refCount", refCount)
 }
 
 func (ep *endpointInfo) Cleanup() {
@@ -1770,10 +1775,14 @@ func (proxier *Proxier) syncProxyRules() {
 
 	// remove stale endpoint refcount entries
 	for epIP := range proxier.terminatedEndpoints {
-		if epToDelete := queriedEndpoints[epIP]; epToDelete != nil && epToDelete.hnsID != "" {
+		klog.V(5).InfoS("Terminated endpoints ready for deletion", "epIP", epIP)
+		if epToDelete := queriedEndpoints[epIP]; epToDelete != nil && epToDelete.hnsID != "" && !epToDelete.IsLocal() {
 			if refCount := proxier.endPointsRefCount.getRefCount(epToDelete.hnsID); refCount == nil || *refCount == 0 {
-				klog.V(3).InfoS("Deleting unreferenced remote endpoint", "hnsID", epToDelete.hnsID)
-				proxier.hns.deleteEndpoint(epToDelete.hnsID)
+				klog.V(3).InfoS("Deleting unreferenced remote endpoint", "hnsID", epToDelete.hnsID, "IP", epToDelete.ip)
+				err := proxier.hns.deleteEndpoint(epToDelete.hnsID)
+				if err != nil {
+					klog.ErrorS(err, "Deleting unreferenced remote endpoint failed", "hnsID", epToDelete.hnsID)
+				}
 			}
 		}
 	}


Test patch:
diff --git a/pkg/proxy/winkernel/hns_test.go b/pkg/proxy/winkernel/hns_test.go
index 74a51b68f311d..ca436394b01a1 100644
--- a/pkg/proxy/winkernel/hns_test.go
+++ b/pkg/proxy/winkernel/hns_test.go
@@ -112,6 +112,70 @@ func TestGetAllEndpointsByNetwork(t *testing.T) {
 	}
 }
 
+func TestGetAllEndpointsByNetworkWithDupEP(t *testing.T) {
+	hcnMock := getHcnMock("L2Bridge")
+	hns := hns{hcn: hcnMock}
+
+	ipv4Config := &hcn.IpConfig{
+		IpAddress: epIpAddress,
+	}
+	ipv6Config := &hcn.IpConfig{
+		IpAddress: epIpv6Address,
+	}
+	remoteEndpoint := &hcn.HostComputeEndpoint{
+		IpConfigurations: []hcn.IpConfig{*ipv4Config, *ipv6Config},
+		MacAddress:       epMacAddress,
+		SchemaVersion: hcn.SchemaVersion{
+			Major: 2,
+			Minor: 0,
+		},
+		Flags: hcn.EndpointFlagsRemoteEndpoint,
+	}
+	Network, _ := hcnMock.GetNetworkByName(testNetwork)
+	remoteEndpoint, err := hns.hcn.CreateEndpoint(Network, remoteEndpoint)
+	if err != nil {
+		t.Error(err)
+	}
+
+	// Create a duplicate local endpoint with the same IP address
+	dupLocalEndpoint := &hcn.HostComputeEndpoint{
+		IpConfigurations: []hcn.IpConfig{*ipv4Config, *ipv6Config},
+		MacAddress:       epMacAddress,
+		SchemaVersion: hcn.SchemaVersion{
+			Major: 2,
+			Minor: 0,
+		},
+	}
+
+	dupLocalEndpoint, err = hns.hcn.CreateEndpoint(Network, dupLocalEndpoint)
+	if err != nil {
+		t.Error(err)
+	}
+
+	mapEndpointsInfo, err := hns.getAllEndpointsByNetwork(Network.Name)
+	if err != nil {
+		t.Error(err)
+	}
+	endpointIpv4, ipv4EpPresent := mapEndpointsInfo[ipv4Config.IpAddress]
+	assert.True(t, ipv4EpPresent, "IPV4 endpoint is missing in Dualstack mode")
+	assert.Equal(t, endpointIpv4.ip, epIpAddress, "IPV4 IP is missing in Dualstack mode")
+	assert.Equal(t, endpointIpv4.hnsID, remoteEndpoint.Id, "HNS ID is not matching with remote endpoint")
+
+	endpointIpv6, ipv6EpPresent := mapEndpointsInfo[ipv6Config.IpAddress]
+	assert.True(t, ipv6EpPresent, "IPV6 endpoint is missing in Dualstack mode")
+	assert.Equal(t, endpointIpv6.ip, epIpv6Address, "IPV6 IP is missing in Dualstack mode")
+	assert.Equal(t, endpointIpv6.hnsID, remoteEndpoint.Id, "HNS ID is not matching with remote endpoint")
+
+	err = hns.hcn.DeleteEndpoint(remoteEndpoint)
+	if err != nil {
+		t.Error(err)
+	}
+	err = hns.hcn.DeleteEndpoint(dupLocalEndpoint)
+	if err != nil {
+		t.Error(err)
+	}
+}
+
 func TestGetEndpointByID(t *testing.T) {
 	// TODO: remove skip once the test has been fixed.
 	t.Skip("Skipping failing test on Windows.")