diff --git a/roles/etcd/tasks/join_etcd_member.yml b/roles/etcd/tasks/join_etcd_member.yml
index 28d259cccd64de30cb8a1d64625638ac5383f740..22440394f2dc8e9d975eb4bf301f43ae546cbc6f 100644
--- a/roles/etcd/tasks/join_etcd_member.yml
+++ b/roles/etcd/tasks/join_etcd_member.yml
@@ -32,6 +32,9 @@
   register: etcd_member_in_cluster
   changed_when: false
   check_mode: no
+  retries: "{{ etcd_retries }}"
+  delay: "{{ retry_stagger | random + 3 }}"
+  until: etcd_member_in_cluster.rc == 0
   tags:
     - facts
   environment:
diff --git a/roles/recover_control_plane/etcd/tasks/main.yml b/roles/recover_control_plane/etcd/tasks/main.yml
index e3dc339307d61f03ed46c8cf8f41894d880996fa..45e2c65e48ad460df28db3c4ca60ebe231976ced 100644
--- a/roles/recover_control_plane/etcd/tasks/main.yml
+++ b/roles/recover_control_plane/etcd/tasks/main.yml
@@ -20,10 +20,9 @@
   when:
     - groups['broken_etcd']
 
-# When there is an error, everything is printed in stderr_lines, even "is healthy" messages.
 - name: Set has_quorum fact
   set_fact:
-    has_quorum: "{{ etcd_endpoint_health.stderr_lines | select('match', '.*is healthy.*') | list | length >= etcd_endpoint_health.stderr_lines | select('match', '.*is unhealthy.*') | list | length }}"
+    has_quorum: "{{ etcd_endpoint_health.stdout_lines | select('match', '.*is healthy.*') | list | length >= etcd_endpoint_health.stderr_lines | select('match', '.*is unhealthy.*') | list | length }}"
   when:
     - groups['broken_etcd']