diff --git a/hgext/acl.py b/hgext/acl.py
--- a/hgext/acl.py
+++ b/hgext/acl.py
@@ -161,7 +161,10 @@ def _getusers(ui, group):
 
     ui.debug('acl: "%s" not defined in [acl.groups]\n' % group)
     # If no users found in group definition, get users from OS-level group
-    return util.groupmembers(group)
+    try:
+        return util.groupmembers(group)
+    except KeyError:
+        raise util.Abort(_("group '%s' is undefined") % group)
 
 def _usermatch(ui, user, usersorgroups):
 
diff --git a/tests/test-acl b/tests/test-acl
--- a/tests/test-acl
+++ b/tests/test-acl
@@ -165,4 +165,12 @@ echo "foo/Bar/** = @group1" >> $config
 echo "@group is allowed inside anything but foo/Bar/"
 do_push fred
 
+echo 'Invalid group'
+# Disable the fakegroups trick to get real failures
+grep -v fakegroups $config > config.tmp
+mv config.tmp $config
+echo '[acl.allow]' >> $config
+echo "** = @unlikelytoexist" >> $config
+do_push fred 2>&1 | grep unlikelytoexist
 
+true
diff --git a/tests/test-acl.out b/tests/test-acl.out
--- a/tests/test-acl.out
+++ b/tests/test-acl.out
@@ -1557,3 +1557,8 @@ abort: acl: access denied for changeset 
 no rollback information available
 0:6675d58eff77
 
+Invalid group
+** = @unlikelytoexist
+acl: "unlikelytoexist" not defined in [acl.groups]
+error: pretxnchangegroup.acl hook failed: group 'unlikelytoexist' is undefined
+abort: group 'unlikelytoexist' is undefined