diff --git a/mercurial/extensions.py b/mercurial/extensions.py
index b6384b3d4ebe67097662d64e028ead2688ed4d2a_bWVyY3VyaWFsL2V4dGVuc2lvbnMucHk=..ea1c2eb7abd341c84422f489af75bccb02622671_bWVyY3VyaWFsL2V4dGVuc2lvbnMucHk= 100644
--- a/mercurial/extensions.py
+++ b/mercurial/extensions.py
@@ -167,9 +167,16 @@
 def _runuisetup(name, ui):
     uisetup = getattr(_extensions[name], 'uisetup', None)
     if uisetup:
-        uisetup(ui)
+        try:
+            uisetup(ui)
+        except Exception as inst:
+            ui.traceback()
+            msg = _forbytes(inst)
+            ui.warn(_("*** failed to set up extension %s: %s\n") % (name, msg))
+            return False
+    return True
 
 def _runextsetup(name, ui):
     extsetup = getattr(_extensions[name], 'extsetup', None)
     if extsetup:
         try:
@@ -171,13 +178,20 @@
 
 def _runextsetup(name, ui):
     extsetup = getattr(_extensions[name], 'extsetup', None)
     if extsetup:
         try:
-            extsetup(ui)
-        except TypeError:
-            if inspect.getargspec(extsetup).args:
-                raise
-            extsetup() # old extsetup with no ui argument
+            try:
+                extsetup(ui)
+            except TypeError:
+                if inspect.getargspec(extsetup).args:
+                    raise
+                extsetup() # old extsetup with no ui argument
+        except Exception as inst:
+            ui.traceback()
+            msg = _forbytes(inst)
+            ui.warn(_("*** failed to set up extension %s: %s\n") % (name, msg))
+            return False
+    return True
 
 def loadall(ui, whitelist=None):
     result = ui.configitems("extensions")
@@ -203,4 +217,5 @@
                 ui.warn(_("*** (%s)\n") % inst.hint)
             ui.traceback()
 
+    broken = set()
     for name in _order[newindex:]:
@@ -206,4 +221,5 @@
     for name in _order[newindex:]:
-        _runuisetup(name, ui)
+        if not _runuisetup(name, ui):
+            broken.add(name)
 
     for name in _order[newindex:]:
@@ -208,6 +224,12 @@
 
     for name in _order[newindex:]:
-        _runextsetup(name, ui)
+        if name in broken:
+            continue
+        if not _runextsetup(name, ui):
+            broken.add(name)
+
+    for name in broken:
+        _extensions[name] = None
 
     # Call aftercallbacks that were never met.
     for shortname in _aftercallbacks:
diff --git a/tests/test-extension.t b/tests/test-extension.t
index b6384b3d4ebe67097662d64e028ead2688ed4d2a_dGVzdHMvdGVzdC1leHRlbnNpb24udA==..ea1c2eb7abd341c84422f489af75bccb02622671_dGVzdHMvdGVzdC1leHRlbnNpb24udA== 100644
--- a/tests/test-extension.t
+++ b/tests/test-extension.t
@@ -1625,6 +1625,5 @@
   > baduisetup = $PWD/baduisetup.py
   > EOF
 
-Broken: an extension that triggers the import of bdiff during uisetup
-can't be easily debugged:
+Even though the extension fails during uisetup, hg is still basically usable:
   $ hg version
@@ -1630,4 +1629,31 @@
   $ hg version
-  abort: No module named bdiff!
-  (did you forget to compile extensions?)
-  [255]
+  *** failed to set up extension baduisetup: No module named bdiff
+  Mercurial Distributed SCM (version *) (glob)
+  (see https://mercurial-scm.org for more information)
+  
+  Copyright (C) 2005-2017 Matt Mackall and others
+  This is free software; see the source for copying conditions. There is NO
+  warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  $ hg version --traceback
+  Traceback (most recent call last):
+    File "*/mercurial/extensions.py", line *, in _runuisetup (glob)
+      uisetup(ui)
+    File "$TESTTMP/baduisetup.py", line 10, in uisetup
+      extensions.wrapfunction(bdiff, 'blocks', blockswrapper)
+    File "*/mercurial/extensions.py", line *, in wrapfunction (glob)
+      origfn = getattr(container, funcname)
+    File "*/hgdemandimport/demandimportpy2.py", line *, in __getattr__ (glob)
+      self._load()
+    File "*/hgdemandimport/demandimportpy2.py", line *, in _load (glob)
+      mod = _hgextimport(_import, head, globals, locals, None, level)
+    File "*/hgdemandimport/demandimportpy2.py", line *, in _hgextimport (glob)
+      return importfunc(name, globals, *args, **kwargs)
+  ImportError: No module named bdiff
+  *** failed to set up extension baduisetup: No module named bdiff
+  Mercurial Distributed SCM (version *) (glob)
+  (see https://mercurial-scm.org for more information)
+  
+  Copyright (C) 2005-2017 Matt Mackall and others
+  This is free software; see the source for copying conditions. There is NO
+  warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
diff --git a/tests/test-flagprocessor.t b/tests/test-flagprocessor.t
index b6384b3d4ebe67097662d64e028ead2688ed4d2a_dGVzdHMvdGVzdC1mbGFncHJvY2Vzc29yLnQ=..ea1c2eb7abd341c84422f489af75bccb02622671_dGVzdHMvdGVzdC1mbGFncHJvY2Vzc29yLnQ= 100644
--- a/tests/test-flagprocessor.t
+++ b/tests/test-flagprocessor.t
@@ -161,7 +161,8 @@
   > EOF
   $ echo 'this should fail' > file
   $ hg commit -Aqm 'add file'
-  abort: cannot register multiple processors on flag '0x8'.
+  *** failed to set up extension duplicate: cannot register multiple processors on flag '0x8'.
+  abort: missing processor for flag '0x1'!
   [255]
 
   $ cd ..