diff --git a/trac/admin/console.py b/trac/admin/console.py
--- a/trac/admin/console.py
+++ b/trac/admin/console.py
@@ -169,9 +169,9 @@ Type:  '?' or 'help' for help on command
         # fixup language according to env settings
         if has_babel:
             default = env.config.get('trac', 'default_language', '')
-            negotiated = get_negotiated_locale([LANG, default])
+            negotiated = get_negotiated_locale([LANG, default], env.log)
             if negotiated:
-                translation.activate(negotiated)
+                translation.activate(negotiated, env.path, env.log)
         
     ##
     ## Utility methods
diff --git a/trac/prefs/web_ui.py b/trac/prefs/web_ui.py
--- a/trac/prefs/web_ui.py
+++ b/trac/prefs/web_ui.py
@@ -106,7 +106,7 @@ class PreferencesModule(Component):
         }
 
         if Locale:
-            locales = map(Locale.parse, get_available_locales())
+            locales = map(Locale.parse, get_available_locales(self.log))
             languages = sorted([(str(locale).replace('_','-'),
                                  locale.display_name) for locale in locales])
             data['locales'] = locales
diff --git a/trac/util/translation.py b/trac/util/translation.py
--- a/trac/util/translation.py
+++ b/trac/util/translation.py
@@ -135,16 +135,20 @@ try:
             finally:
                 self._plugin_domains_lock.release()
 
-        def make_activable(self, get_locale, env_path=None):
-            self._current.args = (get_locale, env_path)
+        def make_activable(self, get_locale, env_path=None, log=None):
+            self._current.args = (get_locale, env_path, log)
 
-        def activate(self, locale, env_path=None):
+        def activate(self, locale, env_path=None, log=None):
             try:
                 locale_dir = pkg_resources.resource_filename('trac', 'locale')
             except pkg_resources.ExtractionError:
                 return # delay extraction
-            except KeyError:
-                return # No locale data in egg
+            except Exception, e:
+                if log is not None:
+                    from trac.util.text import exception_to_unicode
+                    log.error("Unable to find locales: %s",
+                              exception_to_unicode(e))
+                return
             t = Translations.load(locale_dir, locale or 'en_US')
             if not t or t.__class__ is NullTranslations:
                 t = self._null_translations
@@ -174,9 +178,9 @@ try:
         @property
         def isactive(self):
             if self._current.args is not None:
-                get_locale, env_path = self._current.args
+                get_locale, env_path, log = self._current.args
                 self._current.args = None
-                self.activate(get_locale(), env_path)
+                self.activate(get_locale(), env_path, log)
             return self._current.translations is not None
 
         # Delegated methods
@@ -309,15 +313,15 @@ try:
         """
         return translations.reactivate(t)
 
-    def make_activable(get_locale, env_path=None):
+    def make_activable(get_locale, env_path=None, log=None):
         """Defer activation of translations.
         :param get_locale: a callable returning a Babel Locale object
         :param env_path: the environment to use for looking up catalogs
         """
-        translations.make_activable(get_locale, env_path)
+        translations.make_activable(get_locale, env_path, log)
 
-    def activate(locale, env_path=None):
-        translations.activate(locale, env_path)
+    def activate(locale, env_path=None, log=None):
+        translations.activate(locale, env_path, log)
 
     def add_domain(domain, env_path, locale_dir):
         translations.add_domain(domain, env_path, locale_dir)
@@ -325,19 +329,26 @@ try:
     def get_translations():
         return translations
 
-    def get_available_locales():
+    def get_available_locales(log=None):
         """Return a list of locale identifiers of the locales for which
         translations are available.
         """
-        return [dirname for dirname
-                in pkg_resources.resource_listdir('trac', 'locale')
-                if '.' not in dirname]
+        try:
+            return [dirname for dirname
+                    in pkg_resources.resource_listdir('trac', 'locale')
+                    if '.' not in dirname]
+        except Exception, e:
+            if log is not None:
+                from trac.util.text import exception_to_unicode
+                log.error("Unable to find locales: %s",
+                          exception_to_unicode(e))
+            return []
 
-    def get_negotiated_locale(preferred_locales):
+    def get_negotiated_locale(preferred_locales, log=None):
         def normalize(locale_ids):
             return [id.replace('_', '-') for id in locale_ids if id]
         return Locale.negotiate(normalize(preferred_locales),
-                                normalize(get_available_locales()), sep='-')
+                                normalize(get_available_locales(log)), sep='-')
         
     has_babel = True
 
@@ -353,7 +364,7 @@ except ImportError: # fall back on 0.11 
 
     translations = NullTranslationsBabel()
     
-    def activate(locale, env_path=None):
+    def activate(locale, env_path=None, log=None):
         pass
 
     def deactivate():
@@ -362,14 +373,14 @@ except ImportError: # fall back on 0.11 
     def reactivate(t):
         pass
 
-    def make_activable(get_locale, env_path=None):
+    def make_activable(get_locale, env_path=None, log=None):
         pass
 
     def get_translations():
         return translations
 
-    def get_available_locales():
+    def get_available_locales(log=None):
         return []
 
-    def get_negotiated_locale(preferred=None, default=None):
+    def get_negotiated_locale(preferred=None, log=None):
         return None
diff --git a/trac/web/main.py b/trac/web/main.py
--- a/trac/web/main.py
+++ b/trac/web/main.py
@@ -308,7 +308,7 @@ class RequestDispatcher(Component):
             preferred = req.session.get('language')
             default = self.env.config.get('trac', 'default_language', '')
             negotiated = get_negotiated_locale([preferred, default] +
-                                               req.languages)
+                                               req.languages, self.log)
             self.log.debug("Negotiated locale: %s -> %s", preferred, negotiated)
             return negotiated
 
@@ -474,7 +474,8 @@ def dispatch_request(environ, start_resp
         env_error = e
 
     req = Request(environ, start_response)
-    translation.make_activable(lambda: req.locale, env and env.path or None)
+    translation.make_activable(lambda: req.locale, env and env.path or None,
+                               env and env.log or None)
     try:
         return _dispatch_request(req, env, env_error)
     finally:

