Kubernetes Node NotReady: Why Nodes Go NotReady and How to Fix It Kubernetes nodes enter NotReady status when the kubelet fails to renew its Node Lease within 40 seconds, triggering automatic taints and pod evictions after 5 minutes by default, according to Cast AI. The four primary causes are kubelet failure, network or CNI misconfiguration, resource pressure (memory, disk, or PID), and underlying cloud instance failure. Diagnosis begins with `kubectl describe node` and `journalctl -u kubelet`, and Cast AI's autoscaler can automatically provision replacement capacity to reduce recovery time. Key takeaways - When a node becomes NotReady, Kubernetes applies an automatic taint. Pods without tolerations begin evicting within 5 minutes by default. - The kubelet renews its Node Lease every 10 seconds. After 40 seconds without a lease renewal, the node controller marks the node Unknown or NotReady. - Four primary causes exist: kubelet failure, network or CNI misconfiguration, resource pressure memory, disk, or PID , and underlying cloud instance failure. kubectl describe node and journalctl -u kubelet are the two most important first diagnostic tools.- Resource pressure conditions have hard numeric thresholds you can monitor before nodes fail. - Cast AI autoscaler detects pending pods after a NotReady event and provisions replacement capacity automatically, reducing mean time to recovery. What NotReady means Every Kubernetes node reports a set of conditions to the API server. The most important is Ready . When Ready is True, the kubelet is healthy and the node accepts pods. When Ready is False, the kubelet is running but actively reporting a problem. If Ready is Unknown, the API server has received no heartbeat for 40 seconds, which is the default node-monitor-grace-period . Four additional conditions indicate specific resource or network states. Each one tells you something precise about root cause. MemoryPressure: True when memory.available drops below 100Mi the default hard eviction threshold . DiskPressure: True when nodefs.available falls below 10%, nodefs.inodesFree below 5%, or imagefs.available below 15%. PIDPressure: True when available process IDs fall below the eviction threshold. This condition is Linux-only. NetworkUnavailable: True when the CNI plugin has not correctly configured networking on the node. The detection timeline Understanding the timeline matters for triage. Every 10 seconds, the kubelet sends a heartbeat to the API server. The node controller monitors these continuously. After 40 seconds without a heartbeat, the node controller transitions all conditions to Unknown. When a node goes NotReady, the node controller automatically applies two taints: node.kubernetes.io/not-ready:NoExecute and node.kubernetes.io/unreachable:NoExecute . Pods tolerate these taints for 300 seconds 5 minutes by default via tolerationSeconds . After that window, pods without a matching toleration are evicted. The DefaultTolerationSeconds admission controller, enabled by default since Kubernetes 1.8, automatically adds a 300-second toleration for not-ready:NoExecute and unreachable:NoExecute to any pod that does not already define one. As a result, only pods that explicitly set tolerationSeconds: 0 are evicted without delay. All other pods receive the full 300-second grace window. This mechanism replaced the deprecated pod-eviction-timeout flag in Kubernetes 1.24. Therefore, a kubelet restart that completes within 40 seconds produces minimal disruption. However, an outage longer than 5 minutes triggers cascading pod evictions across the cluster. Speed matters: fix the root cause before the eviction window closes. Kubernetes actually uses two heartbeat mechanisms. The primary is the Node Lease object coordination.k8s.io/v1 , which the kubelet renews every 10 seconds. The full NodeStatus update is sent less frequently: approximately every 5 minutes by default. This is why a kubelet that stops suddenly causes Unknown status within 40 seconds: the Lease stops renewing, and the node controller reacts to the lease expiry, not a full status update. How to diagnose a NotReady node Before diagnosing a NotReady node in production, cordon it first to prevent the scheduler from placing new pods there: kubectl cordon