diff --git a/htest/shelltests/htools-invalid.test b/htest/shelltests/htools-invalid.test
index a8160bd361e7e137668e58aa078e347465b35e50..1625b25ba2e093286b8c3551744dc3675402af66 100644
--- a/htest/shelltests/htools-invalid.test
+++ b/htest/shelltests/htools-invalid.test
@@ -25,20 +25,20 @@
 # extra arguments
 ./htest/hspace unexpected-argument
 >>>2
-Error: this program doesn't take any arguments.
+Error: This program doesn't take any arguments.
 >>>=1
 
 ./htest/hbal unexpected-argument
 >>>2
-Error: this program doesn't take any arguments.
+Error: This program doesn't take any arguments.
 >>>=1
 
 ./htest/hinfo unexpected-argument
 >>>2
-Error: this program doesn't take any arguments.
+Error: This program doesn't take any arguments.
 >>>=1
 
 ./htest/hcheck unexpected-argument
 >>>2
-Error: this program doesn't take any arguments.
+Error: This program doesn't take any arguments.
 >>>=1
diff --git a/htools/Ganeti/HTools/ExtLoader.hs b/htools/Ganeti/HTools/ExtLoader.hs
index 534ca7eb2f5fff0dc46907c510822590385af0e3..17a6bed2ba9ad45cfec9f6c88a7c9c2b3a3a6ebc 100644
--- a/htools/Ganeti/HTools/ExtLoader.hs
+++ b/htools/Ganeti/HTools/ExtLoader.hs
@@ -95,7 +95,7 @@ loadExternalData opts = do
       exInsts = optExInst opts
 
   exitWhen (length allSet > 1) "Only one of the rapi, luxi, and data\
-                               \ files options should be given"
+                               \ files options should be given."
 
   util_contents <- maybe (return "") readFile (optDynuFile opts)
   util_data <- exitIfBad "can't parse utilisation data" .
diff --git a/htools/Ganeti/HTools/IAlloc.hs b/htools/Ganeti/HTools/IAlloc.hs
index d85c9ff57a3e5ce05cdc8aeb614cef332a2a1aa2..d7716abbc7e0bbcfc0aae3ee705bdb544e7b0dea 100644
--- a/htools/Ganeti/HTools/IAlloc.hs
+++ b/htools/Ganeti/HTools/IAlloc.hs
@@ -36,8 +36,6 @@ import Data.List
 import Control.Monad
 import Text.JSON (JSObject, JSValue(JSArray),
                   makeObj, encodeStrict, decodeStrict, fromJSObject, showJSON)
-import System.Exit
-import System.IO
 
 import Ganeti.BasicTypes
 import qualified Ganeti.HTools.Cluster as Cluster
@@ -50,6 +48,7 @@ import Ganeti.HTools.CLI
 import Ganeti.HTools.Loader
 import Ganeti.HTools.Types
 import Ganeti.JSON
+import Ganeti.Utils
 
 {-# ANN module "HLint: ignore Eta reduce" #-}
 
@@ -385,9 +384,7 @@ readRequest fp = do
                   "-" -> getContents
                   _   -> readFile fp
   case parseData input_data of
-    Bad err -> do
-      hPutStrLn stderr $ "Error: " ++ err
-      exitWith $ ExitFailure 1
+    Bad err -> exitErr err
     Ok (fix_msgs, rq) -> maybeShowWarnings fix_msgs >> return rq
 
 -- | Main iallocator pipeline.
diff --git a/htools/Ganeti/HTools/Program/Hail.hs b/htools/Ganeti/HTools/Program/Hail.hs
index cb334f1ec66d76527e59ac2702547e625f7a14b3..7231c0df672207af8cd1257f14305143804488f0 100644
--- a/htools/Ganeti/HTools/Program/Hail.hs
+++ b/htools/Ganeti/HTools/Program/Hail.hs
@@ -32,7 +32,6 @@ module Ganeti.HTools.Program.Hail
 import Control.Monad
 import Data.Maybe (fromMaybe, isJust)
 import System.IO
-import System.Exit
 
 import qualified Ganeti.HTools.Cluster as Cluster
 
@@ -41,6 +40,7 @@ import Ganeti.HTools.CLI
 import Ganeti.HTools.IAlloc
 import Ganeti.HTools.Loader (Request(..), ClusterData(..))
 import Ganeti.HTools.ExtLoader (maybeSaveData, loadExternalData)
+import Ganeti.Utils
 
 -- | Options list and functions.
 options :: [OptType]
@@ -58,9 +58,7 @@ arguments = [ArgCompletion OptComplFile 1 (Just 1)]
 
 wrapReadRequest :: Options -> [String] -> IO Request
 wrapReadRequest opts args = do
-  when (null args) $ do
-    hPutStrLn stderr "Error: this program needs an input file."
-    exitWith $ ExitFailure 1
+  when (null args) $ exitErr "This program needs an input file."
 
   r1 <- readRequest (head args)
   if isJust (optDataFile opts) ||  (not . null . optNodeSim) opts
diff --git a/htools/Ganeti/HTools/Program/Hbal.hs b/htools/Ganeti/HTools/Program/Hbal.hs
index e72bf5e721c88a5c9b54a93dbfda997860acc7b7..bc83d059ee4d7a792cdf47b3c768bbb49f03812c 100644
--- a/htools/Ganeti/HTools/Program/Hbal.hs
+++ b/htools/Ganeti/HTools/Program/Hbal.hs
@@ -273,8 +273,7 @@ selectGroup opts gl nlf ilf = do
     hPutStrLn stderr "Found multiple node groups:"
     mapM_ (hPutStrLn stderr . ("  " ++) . Group.name .
            flip Container.find gl . fst) ngroups
-    hPutStrLn stderr "Aborting."
-    exitWith $ ExitFailure 1
+    exitErr "Aborting."
 
   case optGroup opts of
     Nothing -> do
@@ -286,8 +285,7 @@ selectGroup opts gl nlf ilf = do
         hPutStrLn stderr $ "Node group " ++ g ++
           " not found. Node group list is:"
         mapM_ (hPutStrLn stderr . ("  " ++) . Group.name ) (Container.elems gl)
-        hPutStrLn stderr "Aborting."
-        exitWith $ ExitFailure 1
+        exitErr "Aborting."
       Just grp ->
           case lookup (Group.idx grp) ngroups of
             Nothing ->
@@ -350,9 +348,7 @@ checkNeedRebalance opts ini_cv = do
 -- | Main function.
 main :: Options -> [String] -> IO ()
 main opts args = do
-  unless (null args) $ do
-         hPutStrLn stderr "Error: this program doesn't take any arguments."
-         exitWith $ ExitFailure 1
+  unless (null args) $ exitErr "This program doesn't take any arguments."
 
   let verbose = optVerbose opts
       shownodes = optShowNodes opts
diff --git a/htools/Ganeti/HTools/Program/Hcheck.hs b/htools/Ganeti/HTools/Program/Hcheck.hs
index 260a0dfc341281d0e6ea6a8f67d383d0aefba08e..f02b52adb2702ff7dd54a091754d79d608972beb 100644
--- a/htools/Ganeti/HTools/Program/Hcheck.hs
+++ b/htools/Ganeti/HTools/Program/Hcheck.hs
@@ -32,7 +32,6 @@ module Ganeti.HTools.Program.Hcheck
 import Control.Monad
 import Data.List (transpose)
 import System.Exit
-import System.IO
 import Text.Printf (printf)
 
 import qualified Ganeti.HTools.Container as Container
@@ -48,6 +47,7 @@ import Ganeti.HTools.CLI
 import Ganeti.HTools.ExtLoader
 import Ganeti.HTools.Loader
 import Ganeti.HTools.Types
+import Ganeti.Utils
 
 -- | Options list and functions.
 options :: [OptType]
@@ -295,9 +295,7 @@ printFinalHTC = printFinal htcPrefix
 -- | Main function.
 main :: Options -> [String] -> IO ()
 main opts args = do
-  unless (null args) $ do
-         hPutStrLn stderr "Error: this program doesn't take any arguments."
-         exitWith $ ExitFailure 1
+  unless (null args) $ exitErr "This program doesn't take any arguments."
 
   let verbose = optVerbose opts
       machineread = optMachineReadable opts
diff --git a/htools/Ganeti/HTools/Program/Hinfo.hs b/htools/Ganeti/HTools/Program/Hinfo.hs
index b2b47b481d1bd2f69a95d62b1ab9c814397ea51f..367bf0f20fbcc20eade9d135689bd09de724e3a9 100644
--- a/htools/Ganeti/HTools/Program/Hinfo.hs
+++ b/htools/Ganeti/HTools/Program/Hinfo.hs
@@ -31,7 +31,6 @@ module Ganeti.HTools.Program.Hinfo
 
 import Control.Monad
 import Data.List
-import System.Exit
 import System.IO
 
 import Text.Printf (printf)
@@ -154,9 +153,7 @@ commonInfo verbose gl nl il = do
 -- | Main function.
 main :: Options -> [String] -> IO ()
 main opts args = do
-  unless (null args) $ do
-         hPutStrLn stderr "Error: this program doesn't take any arguments."
-         exitWith $ ExitFailure 1
+  unless (null args) $ exitErr "This program doesn't take any arguments."
 
   let verbose = optVerbose opts
       shownodes = optShowNodes opts
diff --git a/htools/Ganeti/HTools/Program/Hspace.hs b/htools/Ganeti/HTools/Program/Hspace.hs
index 6ec9ea68333f07c988be45f18a2dc64bf59fad20..9ad61b803dfa4a493db20aecf2520c25cdfb9a51 100644
--- a/htools/Ganeti/HTools/Program/Hspace.hs
+++ b/htools/Ganeti/HTools/Program/Hspace.hs
@@ -387,7 +387,7 @@ instFromSpec spx =
 -- | Main function.
 main :: Options -> [String] -> IO ()
 main opts args = do
-  exitUnless (null args) "this program doesn't take any arguments"
+  exitUnless (null args) "This program doesn't take any arguments."
 
   let verbose = optVerbose opts
       machine_r = optMachineReadable opts
diff --git a/htools/Ganeti/Utils.hs b/htools/Ganeti/Utils.hs
index 8c1b0ce72c80bea96c60f255d095ed5cccc29045..9636a34d2266124efa37a40bd74b6de8ce373dd8 100644
--- a/htools/Ganeti/Utils.hs
+++ b/htools/Ganeti/Utils.hs
@@ -213,15 +213,13 @@ parseUnit str =
 -- | Unwraps a 'Result', exiting the program if it is a 'Bad' value,
 -- otherwise returning the actual contained value.
 exitIfBad :: String -> Result a -> IO a
-exitIfBad msg (Bad s) = do
-  hPutStrLn stderr $ "Error: " ++ msg ++ ": " ++ s
-  exitWith (ExitFailure 1)
+exitIfBad msg (Bad s) = exitErr (msg ++ ": " ++ s)
 exitIfBad _ (Ok v) = return v
 
 -- | Exits immediately with an error message.
 exitErr :: String -> IO a
 exitErr errmsg = do
-  hPutStrLn stderr $ "Error: " ++ errmsg ++ "."
+  hPutStrLn stderr $ "Error: " ++ errmsg
   exitWith (ExitFailure 1)
 
 -- | Exits with an error message if the given boolean condition if true.
diff --git a/htools/htools.hs b/htools/htools.hs
index f90b676f6291c0c238164bd51c01bdf7fc057118..cec4aa39dbe3157b1d7be8205423994ba50cfeba 100644
--- a/htools/htools.hs
+++ b/htools/htools.hs
@@ -30,7 +30,6 @@ import Control.Monad (guard)
 import Data.Char (toLower)
 import Prelude hiding (catch)
 import System.Environment
-import System.Exit
 import System.IO
 import System.IO.Error (isDoesNotExistError)
 
@@ -45,9 +44,8 @@ usage name = do
   hPutStrLn stderr "This program must be installed under one of the following\
                    \ names:"
   mapM_ (hPutStrLn stderr . ("  - " ++) . fst) personalities
-  hPutStrLn stderr "Please either rename/symlink the program or set\n\
-                   \the environment variable HTOOLS to the desired role."
-  exitWith $ ExitFailure 1
+  exitErr "Please either rename/symlink the program or set\n\
+          \the environment variable HTOOLS to the desired role."
 
 main :: IO ()
 main = do
diff --git a/htools/rpc-test.hs b/htools/rpc-test.hs
index b0cad68c3a14e06b67d9d12e058f8f32a3b4ea5e..394ab9d5949ccfc9a103af3f42b81b3996bf13a0 100644
--- a/htools/rpc-test.hs
+++ b/htools/rpc-test.hs
@@ -37,8 +37,7 @@ import Ganeti.Utils
 usage :: IO ()
 usage = do
   prog <- getProgName
-  hPutStrLn stderr $ "Usage: " ++ prog ++ " delay node..."
-  exitWith $ ExitFailure 1
+  exitErr "Usage: " ++ prog ++ " delay node..."
 
 main :: IO ()
 main = do