diff --git a/gajim/common/helpers.py b/gajim/common/helpers.py
index 76f9642297ce842c3caa5c753d656ff690289af0..6b9a37c47c0fd67ec8e98e63d2cd35dd33035e17 100644
--- a/gajim/common/helpers.py
+++ b/gajim/common/helpers.py
@@ -1213,14 +1213,6 @@ def get_groupchat_name(con, jid):
     return jid.split('@')[0]
 
 
-def get_alternative_venue(error):
-    if error.condition == 'gone' and error.condition_data is not None:
-        uri = parse_uri(error.condition_data)
-        if uri.type == URIType.XMPP and uri.action == URIAction.JOIN:
-            return uri.data['jid']
-    return None
-
-
 def is_affiliation_change_allowed(self_contact, contact, target_aff):
     if contact.affiliation.value == target_aff:
         # Contact has already the target affiliation
diff --git a/gajim/common/modules/discovery.py b/gajim/common/modules/discovery.py
index 67693f2c1fcb709a27e4d69a81233e93e9573cd2..2e863d5f98ae886483704ef2ac8cf12b2ed69e7e 100644
--- a/gajim/common/modules/discovery.py
+++ b/gajim/common/modules/discovery.py
@@ -18,10 +18,12 @@
 from nbxmpp.namespaces import Namespace
 from nbxmpp.structs import StanzaHandler
 from nbxmpp.errors import StanzaError
+from nbxmpp.errors import is_error
 
 from gajim.common import app
 from gajim.common.nec import NetworkIncomingEvent
 from gajim.common.nec import NetworkEvent
+from gajim.common.modules.util import task
 from gajim.common.modules.base import BaseModule
 
 
@@ -192,35 +194,49 @@ def _answer_disco_info(self, _con, stanza, _properties):
         if self._con.get_module('AdHocCommands').command_info_query(stanza):
             raise nbxmpp.NodeProcessed
 
-    def disco_muc(self, jid, callback=None):
-        if not app.account_is_available(self._account):
-            return
+    @task
+    def disco_muc(self,
+                  jid,
+                  request_vcard=False,
+                  allow_redirect=False):
+
+        _task = yield
 
         self._log.info('Request MUC info for %s', jid)
 
-        self.disco_info(jid,
-                        callback=self._muc_info_received,
-                        user_data=callback)
+        result = yield self._nbxmpp('MUC').request_info(
+            jid,
+            request_vcard=request_vcard,
+            allow_redirect=allow_redirect)
 
-    def _muc_info_received(self, task):
-        callback = task.get_user_data()
-        try:
-            result = task.finish()
-        except StanzaError as error:
-            result = error
-            self._log.warning(error)
+        if is_error(result):
+            raise result
 
+        if result.redirected:
+            self._log.info('MUC info received after redirect: %s -> %s',
+                           jid, result.info.jid)
         else:
-            self._log.info('MUC info received: %s', result.jid)
-            app.storage.cache.set_last_disco_info(result.jid, result)
-            self._con.get_module('VCardAvatars').muc_disco_info_update(result)
-            app.nec.push_incoming_event(NetworkEvent(
-                'muc-disco-update',
-                account=self._account,
-                room_jid=result.jid))
-
-        if callback is not None:
-            callback(result)
+            self._log.info('MUC info received: %s', result.info.jid)
+
+        app.storage.cache.set_last_disco_info(result.info.jid, result.info)
+
+        if result.vcard is not None:
+            avatar, avatar_sha = result.vcard.get_avatar()
+            if avatar is not None:
+                if not app.interface.avatar_exists(avatar_sha):
+                    app.interface.save_avatar(avatar)
+
+                app.storage.cache.set_muc_avatar_sha(result.info.jid,
+                                                     avatar_sha)
+                app.interface.avatar_storage.invalidate_cache(result.info.jid)
+
+        self._con.get_module('VCardAvatars').muc_disco_info_update(result.info)
+        app.nec.push_incoming_event(NetworkEvent(
+            'muc-disco-update',
+            account=self._account,
+            room_jid=result.info.jid))
+
+        yield result
 
 
 def get_instance(*args, **kwargs):
diff --git a/gajim/common/modules/muc.py b/gajim/common/modules/muc.py
index 75032b1ca3bb696867b46caf928b5f9232fdbb8c..cb1fde0ffdd67a6cc67fcd78bb5caa14b9123089 100644
--- a/gajim/common/modules/muc.py
+++ b/gajim/common/modules/muc.py
@@ -24,7 +24,7 @@
 from nbxmpp.const import StatusCode
 from nbxmpp.structs import StanzaHandler
 from nbxmpp.util import is_error_result
-from nbxmpp.errors import is_error
+from nbxmpp.errors import StanzaError
 
 from gi.repository import GLib
 
@@ -159,17 +159,19 @@ def create(self, muc_data):
         self._manager.add(muc_data)
         self._create(muc_data)
 
-    def _on_disco_result(self, result):
-        if is_error(result):
-            self._log.info('Disco %s failed: %s', result.jid, result.get_text())
+    def _on_disco_result(self, task):
+        try:
+            result = task.finish()
+        except StanzaError as error:
+            self._log.info('Disco %s failed: %s', error.jid, error.get_text())
             app.nec.push_incoming_event(
                 NetworkEvent('muc-join-failed',
                              account=self._account,
-                             room_jid=result.jid.bare,
-                             error=result))
+                             room_jid=error.jid.bare,
+                             error=error))
             return
 
-        muc_data = self._manager.get(result.jid)
+        muc_data = self._manager.get(result.info.jid)
         if muc_data is None:
             self._log.warning('MUC Data not found, join aborted')
             return
@@ -286,19 +288,22 @@ def _on_config_result(self, result):
         for jid in invites:
             self.invite(result.jid, jid)
 
-    def _on_disco_result_after_config(self, result):
-        if is_error(result):
-            self._log.info('Disco %s failed: %s', result.jid, result.get_text())
+    def _on_disco_result_after_config(self, task):
+        try:
+            result = task.finish()
+        except StanzaError as error:
+            self._log.info('Disco %s failed: %s', error.jid, error.get_text())
             return
 
-        muc_data = self._manager.get(result.jid)
+        jid = result.info.jid
+        muc_data = self._manager.get(jid)
         self._room_join_complete(muc_data)
 
-        self._log.info('Configuration finished: %s', result.jid)
+        self._log.info('Configuration finished: %s', jid)
         app.nec.push_incoming_event(NetworkEvent(
             'muc-configuration-finished',
             account=self._account,
-            room_jid=result.jid))
+            room_jid=jid))
 
     def update_presence(self):
         mucs = self._manager.get_mucs_with_state([MUCJoinedState.JOINED,
diff --git a/gajim/gtk/groupchat_join.py b/gajim/gtk/groupchat_join.py
index 091e9ef7e7d4c9def254c5a7d1d5bd98617233c1..9fa6b2a244c4586d141e86b028ff69d40870330a 100644
--- a/gajim/gtk/groupchat_join.py
+++ b/gajim/gtk/groupchat_join.py
@@ -16,13 +16,12 @@
 from gi.repository import Gdk
 from gi.repository import Pango
 
-from nbxmpp.errors import is_error
+from nbxmpp.errors import StanzaError
 
 from gajim.common import app
 from gajim.common.i18n import _
 from gajim.common.i18n import get_rfc5646_lang
 from gajim.common.helpers import to_user_string
-from gajim.common.helpers import get_alternative_venue
 from gajim.common.helpers import get_group_chat_nick
 from gajim.common.const import MUC_DISCO_ERRORS
 
@@ -89,7 +88,10 @@ def __init__(self, account, jid):
 
         con = app.connections[self.account]
         con.get_module('Discovery').disco_muc(
-            jid, callback=self._disco_info_received)
+            jid,
+            allow_redirect=True,
+            request_vcard=True,
+            callback=self._disco_info_received)
 
     def _on_page_changed(self, stack, _param):
         name = stack.get_visible_child_name()
@@ -97,22 +99,20 @@ def _on_page_changed(self, stack, _param):
         self._nick_chooser.set_sensitive(name == 'info')
 
     @ensure_not_destroyed
-    def _disco_info_received(self, result):
-        if is_error(result):
-            jid = get_alternative_venue(result)
-            if jid is None or self._redirected:
-                self._set_error(result)
-                return
-
-            self.jid = jid
-            self._redirected = True
-            con = app.connections[self.account]
-            con.get_module('Discovery').disco_muc(
-                jid, callback=self._disco_info_received)
-
-        elif result.is_muc:
-            self._muc_info_box.set_from_disco_info(result)
-            nickname = get_group_chat_nick(self.account, result.jid)
+    def _disco_info_received(self, task):
+        try:
+            result = task.finish()
+        except StanzaError as error:
+            self._log.info('Disco %s failed: %s', error.jid, error.get_text())
+            self._set_error(error)
+            return
+
+        if result.redirected:
+            self.jid = result.info.jid
+
+        if result.info.is_muc:
+            self._muc_info_box.set_from_disco_info(result.info)
+            nickname = get_group_chat_nick(self.account, result.info.jid)
             self._nick_chooser.set_text(nickname)
             self._join_button.grab_default()
             self._stack.set_visible_child_name('info')
diff --git a/gajim/gtk/start_chat.py b/gajim/gtk/start_chat.py
index f776281109f1101d57883a3aa446dd791de45ce0..f340f83ab1de9001ec0ad62c8cd901ee0e767e90 100644
--- a/gajim/gtk/start_chat.py
+++ b/gajim/gtk/start_chat.py
@@ -14,7 +14,6 @@
 
 import locale
 from enum import IntEnum
-from functools import partial
 
 from gi.repository import Gdk
 from gi.repository import Gtk
@@ -22,14 +21,13 @@
 from gi.repository import Pango
 
 from nbxmpp.util import is_error_result
-from nbxmpp.errors import is_error
+from nbxmpp.errors import StanzaError
 
 from gajim.common import app
 from gajim.common.helpers import validate_jid
 from gajim.common.helpers import to_user_string
 from gajim.common.helpers import get_groupchat_name
 from gajim.common.helpers import get_group_chat_nick
-from gajim.common.helpers import get_alternative_venue
 from gajim.common.i18n import _
 from gajim.common.i18n import get_rfc5646_lang
 from gajim.common.const import AvatarSize
@@ -293,34 +291,37 @@ def _start_new_chat(self, row):
 
             self.ready_to_destroy = False
             self._redirected = False
-            self._disco_muc(row.account, row.jid)
+            self._disco_muc(row.account, row.jid, request_vcard=row.new)
 
         else:
             app.interface.new_chat_from_jid(row.account, row.jid)
             self.ready_to_destroy = True
 
-    def _disco_muc(self, account, jid):
+    def _disco_muc(self, account, jid, request_vcard):
         self._ui.stack.set_visible_child_name('progress')
         con = app.connections[account]
         con.get_module('Discovery').disco_muc(
-            jid, callback=partial(self._disco_info_received, account))
+            jid,
+            request_vcard=request_vcard,
+            allow_redirect=True,
+            callback=self._disco_info_received,
+            user_data=account)
 
     @ensure_not_destroyed
-    def _disco_info_received(self, account, result):
-        if is_error(result):
-            jid = get_alternative_venue(result)
-            if jid is None or self._redirected:
-                self._set_error(result)
-                return
+    def _disco_info_received(self, task):
+        try:
+            result = task.finish()
+        except StanzaError as error:
+            self._set_error(error)
+            return
 
-            self._redirected = True
-            self._disco_muc(account, jid)
+        account = task.get_user_data()
 
-        elif result.is_muc:
+        if result.info.is_muc:
             self._muc_info_box.set_account(account)
-            self._muc_info_box.set_from_disco_info(result)
+            self._muc_info_box.set_from_disco_info(result.info)
             self._nick_chooser.set_text(get_group_chat_nick(
-                account, result.jid))
+                account, result.info.jid))
             self._ui.stack.set_visible_child_name('info')
 
         else:
@@ -371,7 +372,7 @@ def _on_select_clicked(self, *args):
             return
 
         self._redirected = False
-        self._disco_muc(account, selected_row.jid)
+        self._disco_muc(account, selected_row.jid, request_vcard=True)
 
     def _set_listbox(self, listbox):
         if self._current_listbox == listbox: