Stale PolicyEndpoint when NetworkPolicy podSelector changes, agent keeps enforcing old selector
#238 opened on May 21, 2026
Repository metrics
- Stars
- (54 stars)
- PR merge metrics
- (PR metrics pending)
Description
Description
When the podSelector of an existing NetworkPolicy is updated (e.g. swapped to a value that no longer matches any pod, in order to neutralize the policy), the corresponding PolicyEndpoint CRD (networking.k8s.aws/v1alpha1) is not reconciled. The PolicyEndpoint stays with the previous selector and podSelectorEndpoints list, and the agent keeps enforcing the old rules at the dataplane level.
The PolicyEndpoint only reconciles back to the correct state once it is manually deleted (the controller then recreates it from the up-to-date NetworkPolicy spec).
Environment
- EKS version: 1.34
- EKS Auto Mode: yes (cluster is on Auto Mode, built-in VPC CNI / network-policy controller)
- aws-network-policy-agent: managed via Auto Mode (version not directly visible)
- VPC CNI addon: managed
Reproduce
- Create a NetworkPolicy
np-foowithpodSelector.matchLabels: {app: bar}and any egress rule restricting traffic. Confirm pods labeledapp=barare enforced (DNS works, etc.). - Edit
np-footo changepodSelector.matchLabelsto a value that matches no pod, e.g.{app: disabled-pending-redesign}. Apply. - Wait. Inspect the matching PolicyEndpoint:
kubectl get policyendpoints.networking.k8s.aws -n <ns> -o yaml
Expected
The PolicyEndpoint reconciles to either:
- An empty
podSelectorEndpoints(since the new selector matches no pod), or - It is removed entirely.
Actual
The PolicyEndpoint keeps the original podSelector and podSelectorEndpoints. The agent continues enforcing the old rules on the listed pods, causing things like DNS egress to be denied even though the source NetworkPolicy no longer applies to them.
In one occurrence, the PolicyEndpoint had a creationTimestamp ~29h old while the source NetworkPolicy had been updated multiple hours before — clear evidence the controller never reconciled.
Workaround
Manually delete the stale PolicyEndpoint:
kubectl delete policyendpoints.networking.k8s.aws -n <ns> <pe-name>
The controller (owner=NetworkPolicy) recreates a fresh PolicyEndpoint that reflects the current selector. Pods recover after restarting them (e.g. kubectl delete pod).
For users who actually want to disable network policies entirely on a cluster, the wider cleanup procedure is:
- Set
enableNetworkPolicy: "false"on the AWS VPC CNI addon (via EKS console / awscli) with "Override" conflict resolution - Delete every NetworkPolicy and every PolicyEndpoint cluster-wide
- Replace the nodes to clear stale eBPF state maintained by the agent
The selector-swap scenario described above does not need this full procedure — only deleting the stale PolicyEndpoint is enough.
Related
- aws/aws-network-policy-agent#271 (Network Policy Not Enforced on Initial Creation) — opposite symptom (under-enforcement on creation), but same surface area.
- aws/aws-network-policy-agent#206 (Pod eBPF Map Differs from Policy Endpoint) — adjacent: dataplane state diverging from PolicyEndpoint.