diff --git a/aeron-cluster/src/main/java/io/aeron/cluster/Election.java b/aeron-cluster/src/main/java/io/aeron/cluster/Election.java
index <HASH>..<HASH> 100644
--- a/aeron-cluster/src/main/java/io/aeron/cluster/Election.java
+++ b/aeron-cluster/src/main/java/io/aeron/cluster/Election.java
@@ -677,10 +677,18 @@ class Election
             state(FOLLOWER_CATCHUP, nowNs);
             workCount += 1;
         }
-        else if (nowNs > (timeOfLastUpdateNs + ctx.leaderHeartbeatIntervalNs()) && sendCatchupPosition())
+        else
         {
-            timeOfLastUpdateNs = nowNs;
-            workCount += 1;
+            if (nowNs > (timeOfLastUpdateNs + ctx.leaderHeartbeatIntervalNs()) && sendCatchupPosition())
+            {
+                timeOfLastUpdateNs = nowNs;
+                workCount += 1;
+            }
+
+            if (nowNs >= (timeOfLastStateChangeNs + ctx.leaderHeartbeatTimeoutNs()))
+            {
+                state(INIT, nowNs);
+            }
         }
 
         return workCount;
@@ -741,6 +749,10 @@ class Election
             state(FOLLOWER_READY, nowNs);
             workCount += 1;
         }
+        else if (nowNs >= (timeOfLastStateChangeNs + ctx.leaderHeartbeatTimeoutNs()))
+        {
+            state(INIT, nowNs);
+        }
 
         return workCount;
     }
[Java] Timeout follower if fail to join the catchup or live log.