diff --git a/libempathy/empathy-utils.c b/libempathy/empathy-utils.c
index 49df14b..939b328 100644
--- a/libempathy/empathy-utils.c
+++ b/libempathy/empathy-utils.c
@@ -284,7 +284,7 @@ empathy_presence_from_str (const gchar *str)
 	return TP_CONNECTION_PRESENCE_TYPE_UNSET;
 }
 
-const gchar *
+static const gchar *
 empathy_status_reason_get_default_message (TpConnectionStatusReason reason)
 {
 	switch (reason) {
@@ -321,6 +321,90 @@ empathy_status_reason_get_default_message (TpConnectionStatusReason reason)
 	}
 }
 
+static GHashTable *
+create_errors_to_message_hash (void)
+{
+	GHashTable *errors;
+
+	errors = g_hash_table_new (g_str_hash, g_str_equal);
+	g_hash_table_insert (errors, TP_ERROR_STR_NETWORK_ERROR, _("Network error"));
+	g_hash_table_insert (errors, TP_ERROR_STR_AUTHENTICATION_FAILED,
+		_("Authentication failed"));
+	g_hash_table_insert (errors, TP_ERROR_STR_ENCRYPTION_ERROR,
+		_("Encryption error"));
+	g_hash_table_insert (errors, TP_ERROR_STR_CERT_NOT_PROVIDED,
+		_("Certificate not provided"));
+	g_hash_table_insert (errors, TP_ERROR_STR_CERT_UNTRUSTED,
+		_("Certificate untrusted"));
+	g_hash_table_insert (errors, TP_ERROR_STR_CERT_EXPIRED,
+		_("Certificate expired"));
+	g_hash_table_insert (errors, TP_ERROR_STR_CERT_NOT_ACTIVATED,
+		_("Certificate not activated"));
+	g_hash_table_insert (errors, TP_ERROR_STR_CERT_HOSTNAME_MISMATCH,
+		_("Certificate hostname mismatch"));
+	g_hash_table_insert (errors, TP_ERROR_STR_CERT_FINGERPRINT_MISMATCH,
+		_("Certificate fingerprint mismatch"));
+	g_hash_table_insert (errors, TP_ERROR_STR_CERT_SELF_SIGNED,
+		_("Certificate self-signed"));
+	g_hash_table_insert (errors, TP_ERROR_STR_CANCELLED,
+		_("Status is set to offline"));
+	g_hash_table_insert (errors, TP_ERROR_STR_ENCRYPTION_NOT_AVAILABLE,
+		_("Encryption is not available"));
+	g_hash_table_insert (errors, TP_ERROR_STR_CERT_INVALID,
+		_("Certificate is invalid"));
+	g_hash_table_insert (errors, TP_ERROR_STR_CONNECTION_REFUSED,
+		_("Connection has been refused"));
+	g_hash_table_insert (errors, TP_ERROR_STR_CONNECTION_FAILED,
+		_("Connection can't be established"));
+	g_hash_table_insert (errors, TP_ERROR_STR_CONNECTION_LOST,
+		_("Connection has been lost"));
+	g_hash_table_insert (errors, TP_ERROR_STR_ALREADY_CONNECTED,
+		_("This resource is already connected to the server"));
+	g_hash_table_insert (errors, TP_ERROR_STR_CONNECTION_REPLACED,
+		_("Connection has been replaced by a new connection using the "
+						"same resource"));
+	g_hash_table_insert (errors, TP_ERROR_STR_REGISTRATION_EXISTS,
+		_("The account already exists on the server"));
+	g_hash_table_insert (errors, TP_ERROR_STR_SERVICE_BUSY,
+		_("Server is currently too busy to handle the connection"));
+
+	return errors;
+}
+
+static const gchar *
+empathy_dbus_error_name_get_default_message  (const gchar *error)
+{
+	static GHashTable *errors_to_message = NULL;
+
+	if (error == NULL)
+		return NULL;
+
+	if (G_UNLIKELY (errors_to_message == NULL)) {
+		errors_to_message = create_errors_to_message_hash ();
+	}
+
+	return g_hash_table_lookup (errors_to_message, error);
+}
+
+const gchar *
+empathy_account_get_error_message (TpAccount *account,
+				   TpConnectionStatusReason reason)
+{
+	const gchar *dbus_error;
+	const gchar *message;
+	const GHashTable *details = NULL;
+
+	dbus_error = tp_account_get_detailed_error (account, &details);
+	message = empathy_dbus_error_name_get_default_message (dbus_error);
+	if (message != NULL)
+		return message;
+
+	DEBUG ("Don't understand error '%s'; fallback to the status reason (%u)",
+		dbus_error, reason);
+
+	return empathy_status_reason_get_default_message (reason);
+}
+
 gchar *
 empathy_file_lookup (const gchar *filename, const gchar *subdir)
 {
diff --git a/libempathy/empathy-utils.h b/libempathy/empathy-utils.h
index da0edc5..9930e65 100644
--- a/libempathy/empathy-utils.h
+++ b/libempathy/empathy-utils.h
@@ -75,7 +75,9 @@ guint        empathy_proxy_hash                     (gconstpointer    key);
 gboolean     empathy_check_available_state          (void);
 gint        empathy_uint_compare                    (gconstpointer a,
 						     gconstpointer b);
-const gchar * empathy_status_reason_get_default_message (TpConnectionStatusReason reason);
+
+const gchar * empathy_account_get_error_message (TpAccount *account,
+						 TpConnectionStatusReason reason);
 
 gchar *empathy_protocol_icon_name (const gchar *protocol);
 const gchar *empathy_protocol_name_to_display_name (const gchar *proto_name);
diff --git a/src/empathy-accounts-dialog.c b/src/empathy-accounts-dialog.c
index 46d6298..a3a771c 100644
--- a/src/empathy-accounts-dialog.c
+++ b/src/empathy-accounts-dialog.c
@@ -310,7 +310,7 @@ accounts_dialog_update_status_infobar (EmpathyAccountsDialog *dialog,
                 gchar *message;
 
                 message = g_strdup_printf (_("Offline — %s"),
-                    empathy_status_reason_get_default_message (reason));
+                    empathy_account_get_error_message (account, reason));
                 gtk_info_bar_set_message_type (GTK_INFO_BAR (priv->infobar),
                     GTK_MESSAGE_WARNING);
 
@@ -322,7 +322,7 @@ accounts_dialog_update_status_infobar (EmpathyAccountsDialog *dialog,
                 gchar *message;
 
                 message = g_strdup_printf (_("Disconnected — %s"),
-                    empathy_status_reason_get_default_message (reason));
+                    empathy_account_get_error_message (account, reason));
                 gtk_info_bar_set_message_type (GTK_INFO_BAR (priv->infobar),
                     GTK_MESSAGE_ERROR);
 
diff --git a/src/empathy-main-window.c b/src/empathy-main-window.c
index f0dac63..afca302 100644
--- a/src/empathy-main-window.c
+++ b/src/empathy-main-window.c
@@ -418,7 +418,7 @@ main_window_error_close_clicked_cb (GtkButton         *button,
 static void
 main_window_error_display (EmpathyMainWindow *window,
 			   TpAccount         *account,
-			   const gchar       *message)
+			   TpConnectionStatusReason reason)
 {
 	EmpathyMainWindowPriv *priv = GET_PRIV (window);
 	GtkWidget *info_bar;
@@ -435,7 +435,7 @@ main_window_error_display (EmpathyMainWindow *window,
 
 	str = g_markup_printf_escaped ("<b>%s</b>\n%s",
 					       tp_account_get_display_name (account),
-					       message);
+					       empathy_account_get_error_message (account, reason));
 
 	info_bar = g_hash_table_lookup (priv->errors, account);
 	if (info_bar) {
@@ -571,11 +571,7 @@ main_window_connection_changed_cb (TpAccount  *account,
 
 	if (current == TP_CONNECTION_STATUS_DISCONNECTED &&
 	    reason != TP_CONNECTION_STATUS_REASON_REQUESTED) {
-		const gchar *message;
-
-		message = empathy_status_reason_get_default_message (reason);
-
-		main_window_error_display (window, account, message);
+		main_window_error_display (window, account, reason);
 	}
 
 	if (current == TP_CONNECTION_STATUS_DISCONNECTED) {
