Problem
_HostReconnectionHandler stops retrying after an AuthenticationFailed (cassandra/pool.py:368), and _ReconnectionHandler.run() stops rescheduling once the retry schedule is exhausted. In neither case does the handler remove itself from host._reconnection_handler, so Host.is_currently_reconnecting() (cassandra/pool.py:220) reports a reconnection in progress forever.
Cluster.on_down() consults exactly that to avoid starting a duplicate reconnector (cassandra/cluster.py:2048), and _start_reconnector() (cassandra/cluster.py:1989) -- which would cancel and replace a dead handler -- only runs once on_down() gets past the check. The stale handler therefore gates its own replacement.
A host whose reconnector hit an AuthenticationFailed, which rotated or expired credentials reach, is never reconnected again for the life of the Cluster, even after the credentials are fixed.
Expected behavior
A reconnection handler that will not run again releases the host's reconnector slot, so a later DOWN starts a fresh reconnection as it would for any other host.
ControlConnection's handler has the same shape; that half is fixed in #1024.
Problem
_HostReconnectionHandlerstops retrying after anAuthenticationFailed(cassandra/pool.py:368), and_ReconnectionHandler.run()stops rescheduling once the retry schedule is exhausted. In neither case does the handler remove itself fromhost._reconnection_handler, soHost.is_currently_reconnecting()(cassandra/pool.py:220) reports a reconnection in progress forever.Cluster.on_down()consults exactly that to avoid starting a duplicate reconnector (cassandra/cluster.py:2048), and_start_reconnector()(cassandra/cluster.py:1989) -- which would cancel and replace a dead handler -- only runs onceon_down()gets past the check. The stale handler therefore gates its own replacement.A host whose reconnector hit an
AuthenticationFailed, which rotated or expired credentials reach, is never reconnected again for the life of theCluster, even after the credentials are fixed.Expected behavior
A reconnection handler that will not run again releases the host's reconnector slot, so a later DOWN starts a fresh reconnection as it would for any other host.
ControlConnection's handler has the same shape; that half is fixed in #1024.