diff --git a/mercurial/subrepo.py b/mercurial/subrepo.py
--- a/mercurial/subrepo.py
+++ b/mercurial/subrepo.py
@@ -43,11 +43,16 @@ def state(ctx, ui):
     rev = {}
     if '.hgsubstate' in ctx:
         try:
-            for l in ctx['.hgsubstate'].data().splitlines():
+            for i, l in enumerate(ctx['.hgsubstate'].data().splitlines()):
                 l = l.lstrip()
                 if not l:
                     continue
-                revision, path = l.split(" ", 1)
+                try:
+                    revision, path = l.split(" ", 1)
+                except ValueError:
+                    raise util.Abort(_("invalid subrepository revision "
+                                       "specifier in .hgsubstate line %d")
+                                     % (i + 1))
                 rev[path] = revision
         except IOError, err:
             if err.errno != errno.ENOENT:
diff --git a/tests/test-subrepo-missing.t b/tests/test-subrepo-missing.t
--- a/tests/test-subrepo-missing.t
+++ b/tests/test-subrepo-missing.t
@@ -19,6 +19,15 @@ ignore blanklines in .hgsubstate
   M .hgsubstate
   $ hg revert -qC .hgsubstate
 
+abort more gracefully on .hgsubstate parsing error
+
+  $ cp .hgsubstate .hgsubstate.old
+  >>> file('.hgsubstate', 'wb').write('\ninvalid')
+  $ hg st --subrepos
+  abort: invalid subrepository revision specifier in .hgsubstate line 2
+  [255]
+  $ mv .hgsubstate.old .hgsubstate
+
 delete .hgsub and revert it
 
   $ rm .hgsub