diff --git a/ansible/roles/mariadb/tasks/recover_cluster.yml b/ansible/roles/mariadb/tasks/recover_cluster.yml
index 1d1c340febe6b5fd54444696e9f10d73224a7176..12012a39deccee0296272ed6228a94e12e9c7fbf 100644
--- a/ansible/roles/mariadb/tasks/recover_cluster.yml
+++ b/ansible/roles/mariadb/tasks/recover_cluster.yml
@@ -190,3 +190,5 @@
   when:
     - bootstrap_host is defined
     - bootstrap_host != inventory_hostname
+
+- import_tasks: wait_for_loadbalancer.yml
diff --git a/ansible/roles/mariadb/tasks/register.yml b/ansible/roles/mariadb/tasks/register.yml
index bdcd12eb2ea1dc9c305fb7d6c5f6f2a6b8ad31e4..a2984397e20ab30f3a7c51c912aa71572c8e447f 100644
--- a/ansible/roles/mariadb/tasks/register.yml
+++ b/ansible/roles/mariadb/tasks/register.yml
@@ -13,6 +13,8 @@
       priv: "*.*:USAGE"
   run_once: True
 
+- import_tasks: wait_for_loadbalancer.yml
+
 - name: Creating the Percona XtraBackup database
   kolla_toolbox:
     module_name: mysql_db
diff --git a/ansible/roles/mariadb/tasks/wait_for_loadbalancer.yml b/ansible/roles/mariadb/tasks/wait_for_loadbalancer.yml
new file mode 100644
index 0000000000000000000000000000000000000000..da6bd55c2ed955b052ac513b19397d85c2074351
--- /dev/null
+++ b/ansible/roles/mariadb/tasks/wait_for_loadbalancer.yml
@@ -0,0 +1,16 @@
+---
+# Explicitly wait for the database to be accessible via the load balancer.
+# Sometimes it can reject connections even when all database services are up,
+# due to the health check polling in HAProxy.
+- name: wait for MariaDB to be available via HAProxy
+  wait_for:
+    host: "{{ database_address }}"
+    port: "{{ database_port }}"
+    connect_timeout: 1
+    timeout: 60
+    search_regex: "MariaDB"
+  register: check_mariadb_port
+  until: check_mariadb_port is success
+  retries: 10
+  delay: 6
+  run_once: True