This error occurs when creating a Service with a NodePort that's already in use by another service. Fix it by letting Kubernetes auto-assign the port, finding an available port, or waiting for recently deleted services to release their ports.
Fixes Service port already allocated
# Before (causes conflicts)
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 30004 # Explicit - causes conflicts
# After (automatic assignment)
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
# nodePort omitted - Kubernetes assigns automatically# Before (causes conflicts)apiVersion: v1kind: Servicemetadata:name: my-appspec:type: NodePortports:- port: 8080targetPort: 8080nodePort: 30004 # Explicit - causes conflicts# After (automatic assignment)apiVersion: v1kind: Servicemetadata:name: my-appspec:type: NodePortports:- port: 8080targetPort: 8080# nodePort omitted - Kubernetes assigns automaticallyService port already allocated
The "Service port already allocated" error occurs when you try to create a Kubernetes Service with a NodePort that's already assigned to another service. NodePorts are cluster-wide resources—the same port cannot be used by multiple services across any namespace. The default NodePort range is 30000-32767, providing only 2,768 available ports. When you explicitly specify a nodePort value that's already in use, or when the cluster runs out of ports for dynamic allocation, this error occurs. This error also commonly appears when you delete a service and immediately recreate it with the same port—there's a brief grace period (30-60 seconds) before ports are released back to the pool.
Remove explicit nodePort and let Kubernetes choose:
# Before (causes conflicts)
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 30004 # Explicit - causes conflicts
# After (automatic assignment)
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
# nodePort omitted - Kubernetes assigns automaticallyVerify assigned port:
kubectl get svc my-app
# Check PORT(S) column for assigned NodePortQuery all allocated NodePorts cluster-wide:
# List all NodePort services
kubectl get svc --all-namespaces -o go-template='{{range .items}}{{range.spec.ports}}{{if .nodePort}}{{.nodePort}} - {{$.metadata.namespace}}/{{$.metadata.name}}{{"\n"}}{{end}}{{end}}{{end}}' | sort -nChoose a port not in the list (e.g., 30555):
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
type: NodePort
ports:
- port: 8080
targetPort: 8080
nodePort: 30555 # Use available portPorts take 30-60 seconds to release after deletion:
# Delete service
kubectl delete svc my-app
# Wait for port release
sleep 90
# Recreate with same port
kubectl apply -f service.yamlOr use auto-assignment to avoid waiting:
kubectl delete svc my-app
# Immediately recreate without specifying nodePort
kubectl apply -f service-auto-port.yamlLoadBalancer services allocate internal NodePorts by default. Disable if not needed:
apiVersion: v1
kind: Service
metadata:
name: my-lb
spec:
type: LoadBalancer
allocateLoadBalancerNodePorts: false # No internal NodePort
ports:
- port: 80
targetPort: 8080Only use this if your load balancer supports direct pod routing (AWS NLB IP targets, GCP Container-native LB).
Find the service using your desired port:
# Find which service uses port 30004
kubectl get svc --all-namespaces -o json | \
jq -r '.items[] | select(.spec.ports[]?.nodePort == 30004) | "\(.metadata.namespace)/\(.metadata.name)"'
# Detailed service info
kubectl get svc -A -o wide | grep 30004If it's a service you can modify, either change its port or delete it.
For large clusters, expand the range on kube-apiserver:
# Edit API server manifest
sudo nano /etc/kubernetes/manifests/kube-apiserver.yamlAdd or modify the service port range:
spec:
containers:
- name: kube-apiserver
command:
- kube-apiserver
- --service-node-port-range=20000-40000The API server will automatically restart. Verify:
kubectl get pods -n kube-system -w | grep kube-apiserverWarning: Requires brief control plane downtime.
Default NodePort Range: 30000-32767 (2,768 total ports)
- Configure via --service-node-port-range on kube-apiserver
- Cannot be changed dynamically—requires API server restart
Kubernetes 1.27+ Static Subrange Feature:
Enable ServiceNodePortStaticSubrange=true to split the range:
- Dynamic allocation: Upper band (31384-32767)
- Static allocation: Lower band (30000-31383)
- Reduces collision risk between auto-assigned and explicit ports
Best Practices:
1. Prefer dynamic assignment—omit nodePort field
2. Use Ingress instead of NodePort for HTTP services (shares single port)
3. Document services needing specific ports for firewall rules
4. Monitor port usage: kubectl get svc -A -o json | jq '[.items[].spec.ports[]?.nodePort | select(.)] | length'
5. Consider LoadBalancer services for production workloads
Port Lifecycle:
- Service deletion triggers async port release
- Grace period: 30-60 seconds
- Immediately recreating with same port fails
- Solution: Use dynamic assignment or wait/retry