Skip to main content
cd ../config-traps
risk/register/empty-namespaceselector-networkpolicy-allows-all-traffic.html
Kubernetes Networkinghigh severityKubernetes

An Empty namespaceSelector in a NetworkPolicy Quietly Allows All Traffic

Severity
high
Reviewed
1 Sept 2026
Remediation
~20 minutes
Overview

An empty namespaceSelector in a Kubernetes NetworkPolicy matches all namespaces, not none, silently defeating intended isolation while the policy still shows as applied.

Operational summary

At a glance

Symptom
A NetworkPolicy intended to restrict ingress to a workload from one specific namespace has no visible effect: pods in unrelated namespaces can still reach…
Likely cause
In Kubernetes NetworkPolicy semantics an empty namespaceSelector ({}) matches all namespaces, not none.
Impact
Any pod in any namespace can reach the protected workload on the exposed ports, defeating the intended network segmentation.
Verification signal
Confirm both the intended allow path and the intended deny path with direct traffic tests in an isolated or non-production cluster, not just object inspection, before treating the…
Safe correction
Label the source namespace explicitly and scope the selector to that label so it matches only the intended namespace rather than matching by omission.apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata…
Rollback or recovery
Revert to the previously applied manifest if the corrected policy blocks traffic that must remain permitted while the correct namespace label is confirmed; do not reintroduce an empty…

Symptom

A NetworkPolicy intended to restrict ingress to a workload from one specific namespace has no visible effect: pods in unrelated namespaces can still reach the protected service on the allowed port. kubectl get networkpolicy shows the policy present and applied, and kubectl describe networkpolicy reports no errors. The policy looks syntactically correct and the CNI reports no application failures, yet traffic that should be blocked continues to flow.

False Assumption

The team assumed that writing namespaceSelector: {}, an empty selector with no matchLabels beneath it, restricts traffic to no namespaces, or acts as a safe placeholder until labels are added later. An empty selector was treated as equivalent to an unset or restrictive rule, reasoning that empty should mean nothing matches.

Root Cause

In Kubernetes NetworkPolicy semantics an empty namespaceSelector ({}) matches all namespaces, not none. This mirrors the equally counter-intuitive behaviour of an empty podSelector: {}, which matches all pods. The empty selector is a valid, intentional construct meaning select everything of this kind, but it reads visually like an unfinished or empty rule. The ingress rule believed to be scoped to one namespace was therefore scoped to every namespace in the cluster, including namespaces never intended to be permitted, because label-matching against an empty selector always succeeds.

Impact

Any pod in any namespace can reach the protected workload on the exposed ports, defeating the intended network segmentation. Because the policy object exists and appears attached to the correct pod selector, monitoring that only checks for policy presence, rather than validating actual selector scope, reports the workload as protected. This produces a false sense of isolation: audits pass and dashboards show a NetworkPolicy attached, but the described namespace boundary does not exist in practice.

Diagnosis

Confirm the CNI plugin in use enforces NetworkPolicy at all; some CNIs do not enforce it, which is a separate and distinct failure mode that must be ruled out first. Inspect the raw policy manifest rather than only its summary status, because kubectl describe renders an empty selector block ambiguously.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: restrict-ingress
  namespace: payments
spec:
  podSelector:
    matchLabels:
      app: payments-api
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector: {}

The empty namespaceSelector: {} under from is the defect: it selects every namespace, so the clause imposes no namespace restriction whatsoever. Confirm this by testing connectivity from a namespace that was never intended to have access, rather than relying on the object’s presence alone.

Correction

Label the source namespace explicitly and scope the selector to that label so it matches only the intended namespace rather than matching by omission.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: restrict-ingress
  namespace: payments
spec:
  podSelector:
    matchLabels:
      app: payments-api
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              kubernetes.io/metadata.name: checkout

The built-in kubernetes.io/metadata.name label is applied automatically to namespaces by Kubernetes, so it can be relied on without a separate manual labelling step, reducing the risk that an unlabelled namespace silently falls out of scope. Confirm the exact label value on the target Kubernetes version before relying on it, since label automation behaviour is version-sensitive.

Validation

Confirm both the intended allow path and the intended deny path with direct traffic tests in an isolated or non-production cluster, not just object inspection, before treating the correction as verified.

  • Deploy a test pod in the intended source namespace (checkout) and confirm it can reach the protected service on the allowed port.
  • Deploy a test pod in an unrelated namespace and confirm the connection is refused or times out, demonstrating the namespace restriction now actually applies.
  • Re-run kubectl get pods -n payments -o wide alongside the connectivity tests to confirm no change to pod scheduling or readiness resulted from the policy edit.

Rollback

Revert to the previously applied manifest if the corrected policy blocks traffic that must remain permitted while the correct namespace label is confirmed; do not reintroduce an empty selector as a temporary fix.

Keep the previous manifest version under version control before editing, so rollback is a direct re-apply of a known-good file rather than a reconstruction from memory. Stop condition: if connectivity tests show unexpected denial to a namespace that must have access, halt further policy changes and re-verify the exact label value on the source namespace with a read-only label query before reapplying any corrected policy. Because reapplying a NetworkPolicy is a namespace-scoped, reversible configuration change with a known prior state on file, it should only proceed after the prior manifest has been confirmed retrievable, and any reapply should be executed by an operator with the necessary RBAC permissions and observed for effect before wider rollout.

Prevention

Treat every namespaceSelector and podSelector in a NetworkPolicy as matching everything by default unless matchLabels or matchExpressions is explicitly populated. During review, flag any selector block with no key-value pairs beneath it as a defect requiring explicit justification, not an accepted placeholder. Where a policy is genuinely intended to deny all ingress from other namespaces, use an explicit default-deny policy with no from clause at all, rather than an empty selector, because the two constructs are not equivalent and read very differently in a diff. Confirm selector-matching semantics against the exact Kubernetes version deployed, since NetworkPolicy API behaviour is version-sensitive and should not be assumed constant across releases.

03

Apply the safer control

Before you change production

Confirm the affected scope, export the current configuration, and test the replacement control in a non-production environment first.

Fix commands and configuration

kubectl get networkpolicy
kubectl describe networkpolicy
namespaceSelector: {}
04

Verify, roll back or escalate

Verify

Confirm both the intended allow path and the intended deny path with direct traffic tests in an isolated or non-production cluster, not just object inspection, before treating the correction as verified.Deploy a test pod in the intended source namespace (checkout)…

Rollback

Revert to the previously applied manifest if the corrected policy blocks traffic that must remain permitted while the correct namespace label is confirmed; do not reintroduce an empty selector as a temporary fix.Keep the previous manifest version under version control…

Escalate

Escalate when the blast radius is uncertain, the control cannot be tested safely, or remediation requires an outage or security exception.

After remediation

Further reading stays below the corrective workflow and is selected by platform, category and shared technical keywords.

Discover more

Connected KBY resources