diff --git a/mercurial/repoview.py b/mercurial/repoview.py
--- a/mercurial/repoview.py
+++ b/mercurial/repoview.py
@@ -150,6 +150,13 @@ def tryreadcache(repo, hideable):
                 count = len(data) / 4
                 hidden = frozenset(struct.unpack('>%ii' % count, data))
         return hidden
+    except struct.error:
+        repo.ui.debug('corrupted hidden cache\n')
+        # No need to fix the content as it will get rewritten
+        return None
+    except (IOError, OSError):
+        repo.ui.debug('cannot read hidden cache\n')
+        return None
     finally:
         if fh:
             fh.close()
diff --git a/tests/test-obsolete.t b/tests/test-obsolete.t
--- a/tests/test-obsolete.t
+++ b/tests/test-obsolete.t
@@ -951,6 +951,23 @@ Test heads computation on pending index 
   $ hg amendtransient
   [1, 3]
 
+Check that corrupted hidden cache does not crash
+
+  $ printf "" > .hg/cache/hidden
+  $ hg log -r . -T '{node}' --debug
+  corrupted hidden cache
+  8fd96dfc63e51ed5a8af1bec18eb4b19dbf83812 (no-eol)
+  $ hg log -r . -T '{node}' --debug
+  8fd96dfc63e51ed5a8af1bec18eb4b19dbf83812 (no-eol)
+
+Check that wrong hidden cache permission does not crash
+
+  $ chmod 000 .hg/cache/hidden
+  $ hg log -r . -T '{node}' --debug
+  cannot read hidden cache
+  error writing hidden changesets cache
+  8fd96dfc63e51ed5a8af1bec18eb4b19dbf83812 (no-eol)
+
 Test cache consistency for the visible filter
 1) We want to make sure that the cached filtered revs are invalidated when
 bookmarks change