Kubernetes Service Has No Endpoints — Selector Mismatch
Fix a Service with no endpoints by matching the selector to pod labels and confirming pods are Ready.
Symptoms
- kubectl get endpoints <svc> shows "<none>" as the endpoint
- Clients get connection refused although pods are running
- The service worked before a label change
Possible causes
- The Service selector does not match any pod labels
- Matching pods are not Ready, so they are excluded from endpoints
- A namespace or label typo means the selector targets nothing
Diagnosis steps
Compare the selector with pod labels
kubectl get svc <svc> -o jsonpath="{.spec.selector}"; kubectl get pods --show-labelsInterpretation
An empty endpoints list with non-matching labels confirms a selector mismatch.
Check endpoint slices and readiness
kubectl get endpointslices -l kubernetes.io/service-name=<svc> -o yaml | grep -A 5 conditionsInterpretation
EndpointSlices list ready addresses; if empty, the pods are not Ready.
Root cause
A Service routes to pods whose labels match its selector and that are Ready. If the selector matches nothing or matching pods fail readiness, the endpoint list is empty and connections are refused.
Fix
Align the Service selector with stable pod labels, fix readiness probes so pods become Ready, and avoid over-specific or typo labels in selectors.
Risk note
A too-broad selector can route traffic to unintended pods; keep selectors specific to the workload.
Verify the fix
Confirm the endpoints list is populated with pod IPs and that kubectl get endpoints reports ready addresses; test connectivity through the service.
Symptoms
When you hit “Kubernetes Service Has No Endpoints — Selector Mismatch”, guessing wastes time. The guide below follows evidence: reproduce the symptom, run targeted diagnostics, identify the root cause, apply the fix, and verify it with concrete checks.
Observed symptoms include:
- kubectl get endpoints
shows “ ” as the endpoint - Clients get connection refused although pods are running
- The service worked before a label change
Reproduce and Diagnose
Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.
Step 1: Compare the selector with pod labels
kubectl get svc <svc> -o jsonpath="{.spec.selector}"; kubectl get pods --show-labels
An empty endpoints list with non-matching labels confirms a selector mismatch.
Step 2: Check endpoint slices and readiness
kubectl get endpointslices -l kubernetes.io/service-name=<svc> -o yaml | grep -A 5 conditions
EndpointSlices list ready addresses; if empty, the pods are not Ready.
Likely contributors, in order of frequency:
- The Service selector does not match any pod labels
- Matching pods are not Ready, so they are excluded from endpoints
- A namespace or label typo means the selector targets nothing
Root Cause
A Service routes to pods whose labels match its selector and that are Ready. If the selector matches nothing or matching pods fail readiness, the endpoint list is empty and connections are refused.
The Fix
Align the Service selector with stable pod labels, fix readiness probes so pods become Ready, and avoid over-specific or typo labels in selectors.
Watch out: A too-broad selector can route traffic to unintended pods; keep selectors specific to the workload.
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web # must match pod labels below
ports:
- port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
spec:
template:
metadata:
labels:
app: web # <- matched by the selector
spec:
containers:
- name: web
ports: [{ containerPort: 8080 }]
Verify and Prevent
Confirm the endpoints list is populated with pod IPs and that kubectl get endpoints reports ready addresses; test connectivity through the service.
Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.
This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.