How to fix Flannel No Subnet Available in Kubernetes

KubernetesADVANCEDHIGHUpdated Dec 6, 2025· 142 views

The "Flannel No Subnet Available" error occurs when Flannel cannot allocate a pod network subnet to a node. This prevents pods from being assigned IP addresses, blocking pod scheduling. The error is usually caused by CIDR pool exhaustion or configuration issues.

Quick fix

Fixes Flannel No Subnet Available

# Check pod CIDR in cluster config:
kubectl cluster-info dump | grep -i "pod-network-cidr"

# View subnet allocations for each node:
kubectl get nodes -o jsonpath='{.items[*].spec.podCIDR}'

# Or more detailed:
kubectl get nodes -o json | jq '.items[] | {name: .metadata.name, podCIDR: .spec.podCIDR}'

# Check Flannel subnet data in etcd:
kubectl exec -it <etcd-pod> -n kube-system -- etcdctl get --prefix /coreos.com/network/subnets
  1. Check current subnet allocation
  2. Verify Flannel configuration
  3. Calculate subnet exhaustion
  4. Check for stale node allocations in etcd
kubernetes — error
# Check pod CIDR in cluster config:
kubectl cluster-info dump | grep -i "pod-network-cidr"
# View subnet allocations for each node:
kubectl get nodes -o jsonpath='{.items[*].spec.podCIDR}'
# Or more detailed:
kubectl get nodes -o json | jq '.items[] | {name: .metadata.name, podCIDR: .spec.podCIDR}'
# Check Flannel subnet data in etcd:
kubectl exec -it <etcd-pod> -n kube-system -- etcdctl get --prefix /coreos.com/network/subnets
Flannel No Subnet Available

What this error means

Flannel manages pod IP address allocation by assigning a subnet to each node from a larger CIDR pool. When a new node joins: 1. Flannel tries to allocate a /24 subnet from the pod CIDR 2. Stores the allocation in etcd 3. If all subnets are exhausted, allocation fails 4. Pods cannot be assigned IPs on that node Example: - Pod CIDR: 10.244.0.0/16 (65,536 IPs, ~256 /24 subnets) - Node 1 gets: 10.244.0.0/24 - Node 2 gets: 10.244.1.0/24 - Node 256 gets: 10.244.255.0/24 - Node 257: ERROR - no subnet available

Typical symptoms

  • Pod status shows "Pending" with message "no subnet available"
  • Events show "no subnet available for: nodes/xxx"
  • kubectl describe pod shows Flannel allocation error
  • New nodes cannot schedule pods
  • Scale-up fails when adding new nodes
  • Nodes have 0 ready pods despite sufficient resources
  • Flannel daemon logs show allocation errors

Common causes

  1. Pod CIDR pool too small for number of nodes
  2. Node subnet allocation fragmented (subnets allocated but not released)
  3. Stale node objects in etcd with allocated subnets
  4. Flannel configuration changed after cluster creation
  5. etcd corruption or stale allocation data
  6. Multiple Flannel instances causing duplicate allocations
  7. Cluster scaled beyond design capacity

How to fix "Flannel No Subnet Available"

1Check current subnet allocation

View which subnets are allocated:

bash
# Check pod CIDR in cluster config:
kubectl cluster-info dump | grep -i "pod-network-cidr"

# View subnet allocations for each node:
kubectl get nodes -o jsonpath='{.items[*].spec.podCIDR}'

# Or more detailed:
kubectl get nodes -o json | jq '.items[] | {name: .metadata.name, podCIDR: .spec.podCIDR}'

# Check Flannel subnet data in etcd:
kubectl exec -it <etcd-pod> -n kube-system -- etcdctl get --prefix /coreos.com/network/subnets

Note: You need etcd access (usually in kube-system namespace).

2Verify Flannel configuration

Check the configured pod CIDR:

bash
# View Flannel config:
kubectl get cm kube-flannel-cfg -n kube-flannel -o yaml

# Extract Network:
kubectl get cm kube-flannel-cfg -n kube-flannel -o jsonpath='{.data.net-conf\.json}' | jq .Network

# Expected output: "10.244.0.0/16" or similar

# Also check SubnetLen (subnet size, default /24):
kubectl get cm kube-flannel-cfg -n kube-flannel -o jsonpath='{.data.net-conf\.json}' | jq .SubnetLen

Default is /24, which gives 256 subnets for a /16 network.

3Calculate subnet exhaustion

Determine if you've run out of subnets:

bash
# Count nodes:
kUBECTL_NODES=$(kubectl get nodes --no-headers | wc -l)
echo "Total nodes: $KUBECTL_NODES"

# Get pod CIDR:
POD_CIDR=$(kubectl cluster-info dump | grep "pod-network-cidr" | head -1 | cut -d= -f2)
echo "Pod CIDR: $POD_CIDR"

# For /16 with /24 subnets: 256 subnets max
# For /16 with /25 subnets: 512 subnets max

# If KUBECTL_NODES > 256, you need a larger CIDR or smaller subnets
if [ $KUBECTL_NODES -gt 256 ]; then
  echo "ERROR: Cluster has more than 256 nodes but using /16 CIDR with /24 subnets"
fi

Calculate available subnets: (2^(16-24)) = 256 with default settings.

4Check for stale node allocations in etcd

Find orphaned subnet allocations:

bash
# Get all allocated subnets from etcd:
kubectl exec -it <etcd-pod> -n kube-system -- etcdctl get --prefix /coreos.com/network/subnets | less

# Get existing nodes:
kubectl get nodes -o jsonpath='{.items[*].metadata.name}'

# Compare: if etcd has subnets for nodes that don't exist, they're stale

# Manually delete stale allocations (dangerous—do with caution):
kubectl exec <etcd-pod> -n kube-system -- etcdctl del /coreos.com/network/subnets/<stale-key>

Stale allocations prevent new nodes from getting subnets.

5Expand the pod CIDR (requires cluster recreation)

If exhausted, you need a larger network (full cluster migration):

Option 1: Use larger CIDR on new cluster

bash
# When creating cluster, use /14 instead of /16:
kubeadm init --pod-network-cidr=10.244.0.0/14  # 4x larger (1024 subnets with /24)

Option 2: Migrate to new cluster
1. Create new cluster with larger CIDR
2. Drain old cluster pods: kubectl drain --all-namespaces
3. Migrate data/state
4. Point traffic to new cluster

Option 3: Change subnet size (not recommended)

bash
# Use smaller subnets (/25 = 512 subnets per /16):
kubectl patch cm kube-flannel-cfg -n kube-flannel -p '{"data":{"net-conf.json":"...SubnetLen: 25..."}}'

Smaller subnets = more nodes supported, but less IP per node.

6Clean up stale nodes from the cluster

Remove nodes that no longer exist:

bash
# Find nodes in NotReady state:
kubectl get nodes

# Drain pod before deletion:
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data

# Delete the node:
kubectl delete node <node-name>

# Verify:
kubectl get nodes

Deleting nodes also frees their subnet allocations.

7Restart Flannel to recompute allocations

Force Flannel to recalculate subnet assignments:

bash
# Restart the Flannel DaemonSet:
kubectl rollout restart daemonset/kube-flannel -n kube-flannel

# Watch for pod restarts:
kubectl get pods -n kube-flannel -w

# Check logs:
kubectl logs -n kube-flannel -l app=flannel -f

# Monitor node pod CIDR assignment:
watch kubectl get nodes -o wide

After restart, verify all nodes have podCIDR assignments.

8Monitor subnet usage and scale limits

Set up monitoring to prevent future exhaustion:

bash
# Create Prometheus alert:
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: flannel-alerts
spec:
  groups:
  - name: flannel
    rules:
    - alert: FlannelSubnetExhaustion
      expr: |
        count(kube_node_labels{label_kubernetes_io_os="linux"}) > 240
      annotations:
        summary: "Approaching Flannel subnet limit (240+ nodes)"

Planning:
- If using /16 CIDR, maximum ~256 nodes
- For larger clusters, use /14 (1024 nodes) or /12 (4096 nodes)
- Monitor: kubectl get nodes | wc -l

Advanced notes

Subnet exhaustion is usually discovered during rapid scaling. Default /16 CIDR with /24 subnets supports exactly 256 nodes—this can be tight for large deployments. For production, plan CIDR carefully: /14 is common (1024 nodes), /12 for very large clusters (4096 nodes). Stale allocations in etcd are rare but can happen if nodes are force-deleted without proper cleanup. MultiUS (multi-subnet) mode is not Flannel's strength; for large deployments, consider Calico or other more advanced CNIs. Flannel stores all state in etcd; etcd performance degrades with large cluster sizes (etcd is not designed for 10k+ keys). Monitor etcd size: etcdctl endpoint status. For migration paths: use in-place kubeadm upgrade to /14 CIDR if possible, or planned migration to new cluster.

Frequently asked questions

What does "Flannel No Subnet Available" mean?
Flannel manages pod IP address allocation by assigning a subnet to each node from a larger CIDR pool. When a new node joins: 1. Flannel tries to allocate a /24 subnet from the pod CIDR 2.
How do I fix "Flannel No Subnet Available"?
The "Flannel No Subnet Available" error occurs when Flannel cannot allocate a pod network subnet to a node. This prevents pods from being assigned IP addresses, blocking pod scheduling. The error is usually caused by CIDR pool exhaustion or configuration issues.
What causes "Flannel No Subnet Available"?
Pod CIDR pool too small for number of nodes Node subnet allocation fragmented (subnets allocated but not released) Stale node objects in etcd with allocated subnets
Is the "Flannel No Subnet Available" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading