diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,6 +1,18 @@
+## 1.9
+
++ Update status code of missing host responses.
+  They now emit a 502 on missing host, and 404 on host not found
++ Always restart keter in the nix config for systemd.
+  It turns out that keter may exit with exit code 0 under load testing.
+  Changing from on-failure to always in systemd should bring it back up.
++ Squash proxy exceptions if they occur and serve a default or custom error
+  response.
+  Emits the exception to the log.
++ Add incoming folder to the CI build.
+
 ## 1.8.4
 
-+ Get rid of ominious warning at the top, "Hackage documentation generation is not reliable.."
++ Get rid of ominious warning at the top.
   Thanks to /u/Opposite-Platypus-99
   for pointing this out.
 
diff --git a/Keter/Main.hs b/Keter/Main.hs
--- a/Keter/Main.hs
+++ b/Keter/Main.hs
@@ -70,7 +70,7 @@
     log StartWatching
     startWatching kc appMan log
     log StartListening
-    startListening kc hostman
+    startListening log kc hostman
 
 -- | Load up Keter config.
 withConfig :: FilePath
@@ -217,9 +217,9 @@
              return [fp1]
            ) (filter (\x -> x /= "." && x /= "..") dir)
 
-startListening :: KeterConfig -> HostMan.HostManager -> IO ()
-startListening config hostman = do
-    settings <- Proxy.makeSettings config hostman
+startListening :: (LogMessage -> IO ()) -> KeterConfig -> HostMan.HostManager -> IO ()
+startListening log config hostman = do
+    settings <- Proxy.makeSettings log config hostman
     runAndBlock (kconfigListeners config) $ Proxy.reverseProxy settings
 
 runAndBlock :: NonEmptyVector a
diff --git a/Keter/Proxy.hs b/Keter/Proxy.hs
--- a/Keter/Proxy.hs
+++ b/Keter/Proxy.hs
@@ -48,12 +48,13 @@
                                                     setLpsTimeBound,
                                                     waiProxyToSettings,
                                                     wpsSetIpHeader,
+                                                    wpsOnExc,
                                                     wpsGetDest)
 import qualified Network.HTTP.ReverseProxy.Rewrite as Rewrite
 import           Network.HTTP.Types                (mkStatus, status200,
                                                     status301, status302,
                                                     status303, status307,
-                                                    status404)
+                                                    status404, status502)
 import qualified Network.Wai                       as Wai
 import           Network.Wai.Application.Static    (defaultFileServerSettings,
                                                     ssListing, staticApp)
@@ -77,15 +78,17 @@
 
 data ProxySettings = MkProxySettings
   { -- | Mapping from virtual hostname to port number.
-    psHostLookup  :: ByteString -> IO (Maybe (ProxyAction, TLS.Credentials))
-  , psManager     :: !Manager
-  , psConfig      :: !KeterConfig
-  , psUnkownHost  :: ByteString -> ByteString
-  , psMissingHost :: ByteString
+    psHostLookup     :: ByteString -> IO (Maybe (ProxyAction, TLS.Credentials))
+  , psManager        :: !Manager
+  , psConfig         :: !KeterConfig
+  , psUnkownHost     :: ByteString -> ByteString
+  , psMissingHost    :: ByteString
+  , psProxyException :: ByteString
+  , psLogException   :: Wai.Request -> SomeException -> IO ()
   }
 
-makeSettings :: KeterConfig -> HostMan.HostManager -> IO ProxySettings
-makeSettings psConfig@KeterConfig {..} hostman = do
+makeSettings :: (LogMessage -> IO ()) -> KeterConfig -> HostMan.HostManager -> IO ProxySettings
+makeSettings log psConfig@KeterConfig {..} hostman = do
     psManager <- HTTP.newManager HTTP.tlsManagerSettings
     psMissingHost <- case kconfigMissingHostResponse of
       Nothing -> pure defaultMissingHostBody
@@ -93,8 +96,12 @@
     psUnkownHost <- case kconfigUnknownHostResponse  of
                 Nothing -> pure defaultUnknownHostBody
                 Just x -> const <$> taggedReadFile "missing-host-response-file" x
+    psProxyException <- case kconfigProxyException of
+                Nothing -> pure defaultProxyException
+                Just x -> taggedReadFile "proxy-exception-response-file" x
     pure $ MkProxySettings{..}
     where
+        psLogException a b = log $ ProxyException a b
         psHostLookup = HostMan.lookupAction hostman . CI.mk
 
 taggedReadFile :: String -> FilePath -> IO ByteString
@@ -132,6 +139,8 @@
         s { WarpTLS.tlsServerHooks = newHooks{TLS.onServerNameIndication = newOnServerNameIndication}
           , WarpTLS.tlsSessionManagerConfig = if session then (Just TLSSession.defaultConfig) else Nothing }
 
+
+
 withClient :: Bool -- ^ is secure?
            -> ProxySettings
            -> Wai.Application
@@ -144,6 +153,7 @@
                 then SIHFromHeader
                 else SIHFromSocket
         ,  wpsGetDest = Just getDest
+        ,  wpsOnExc = handleProxyException psLogException psProxyException
         } psManager
   where
     useHeader :: Bool
@@ -273,12 +283,20 @@
         , Wai.rawQueryString req
         ]
 
+handleProxyException :: (Wai.Request -> SomeException -> IO ()) -> ByteString -> SomeException -> Wai.Application
+handleProxyException handleException onexceptBody except req respond = do
+  handleException req except
+  respond $ missingHostResponse onexceptBody
+
+defaultProxyException :: ByteString
+defaultProxyException = "<!DOCTYPE html>\n<html><head><title>Welcome to Keter</title></head><body><h1>Welcome to Keter</h1><p>There was a proxy error, check the keter logs for details.</p></body></html>"
+
 defaultMissingHostBody :: ByteString
 defaultMissingHostBody = "<!DOCTYPE html>\n<html><head><title>Welcome to Keter</title></head><body><h1>Welcome to Keter</h1><p>You did not provide a virtual hostname for this request.</p></body></html>"
 
 missingHostResponse :: ByteString -> Wai.Response
 missingHostResponse missingHost = Wai.responseBuilder
-    status200
+    status502
     [("Content-Type", "text/html; charset=utf-8")]
     $ copyByteString missingHost
 
@@ -289,7 +307,7 @@
 
 unknownHostResponse :: ByteString -> ByteString -> Wai.Response
 unknownHostResponse host body = Wai.responseBuilder
-    status200
+    status404
     [("Content-Type", "text/html; charset=utf-8"),
      ("X-Forwarded-Host",
       -- if an attacker manages to insert line breaks somehow,
diff --git a/Keter/Types/Common.hs b/Keter/Types/Common.hs
--- a/Keter/Types/Common.hs
+++ b/Keter/Types/Common.hs
@@ -14,6 +14,7 @@
     , SomeException
     ) where
 
+import qualified Network.Wai                       as Wai
 import           Control.Exception          (Exception, SomeException)
 import           Data.Aeson                 (FromJSON, Object, ToJSON,
                                              Value (Bool), object, withBool,
@@ -94,6 +95,7 @@
     | BindCli AddrInfo
     | ReceivedCliConnection SockAddr
     | KillingApp Port Text
+    | ProxyException Wai.Request SomeException
 
 instance Show LogMessage where
     show (ProcessCreated f) = "Created process: " ++ f
@@ -161,6 +163,7 @@
     show StartListening = "Started listening"
     show (BindCli addr) = "Bound cli to " <> show addr
     show (ReceivedCliConnection peer) = "CLI Connection from " <> show peer
+    show (ProxyException req except) = "Got a proxy exception on request " <> show req <> " with exception "  <> show except
 
 data KeterException = CannotParsePostgres FilePath
                     | ExitCodeFailure FilePath ExitCode
diff --git a/Keter/Types/V10.hs b/Keter/Types/V10.hs
--- a/Keter/Types/V10.hs
+++ b/Keter/Types/V10.hs
@@ -107,7 +107,8 @@
     -- ^ Port for the cli to listen on
 
     , kconfigUnknownHostResponse  :: !(Maybe F.FilePath)
-    , kconfigMissingHostResponse :: !(Maybe F.FilePath)
+    , kconfigMissingHostResponse  :: !(Maybe F.FilePath)
+    , kconfigProxyException       :: !(Maybe F.FilePath)
     }
 
 instance ToCurrent KeterConfig where
@@ -126,6 +127,7 @@
         , kconfigCliPort             = Nothing
         , kconfigUnknownHostResponse  = Nothing
         , kconfigMissingHostResponse = Nothing
+        , kconfigProxyException      = Nothing
         }
       where
         getSSL Nothing = V.empty
@@ -152,6 +154,7 @@
         , kconfigCliPort             = Nothing
         , kconfigUnknownHostResponse  = Nothing
         , kconfigMissingHostResponse = Nothing
+        , kconfigProxyException      = Nothing
         }
 
 instance ParseYamlFile KeterConfig where
@@ -175,6 +178,7 @@
             <*> o .:? "cli-port"
             <*> o .:? "missing-host-response-file"
             <*> o .:? "unknown-host-response-file"
+            <*> o .:? "proxy-exception-response-file"
 
 -- | Whether we should force redirect to HTTPS routes.
 type RequiresSecure = Bool
diff --git a/keter.cabal b/keter.cabal
--- a/keter.cabal
+++ b/keter.cabal
@@ -1,6 +1,6 @@
 Cabal-version:       >=1.10
 Name:                keter
-Version:             1.8.4
+Version:             1.9
 Synopsis:            Web application deployment manager, focusing on Haskell web frameworks
 Description:
     Deployment system for web applications, originally intended for hosting Yesod
@@ -9,12 +9,10 @@
     * Binds to the main port (usually port 80) and reverse proxies requests to your application based on virtual hostnames.
     * Provides SSL support if requested.
     * Automatically launches applications, monitors processes, and relaunches any processes which die.
-    * Provides graceful redeployment support, by launching a second copy of your application, performing a health check[1], and then switching reverse proxying to the new process.
+    * Provides graceful redeployment support, by launching a second copy of your application, performing a health check, and then switching reverse proxying to the new process.
     * Management of log files.
     .
     Keter provides many more advanced features and extension points. It allows configuration of static hosts, redirect rules, management of PostgreSQL databases, and more. It supports a simple bundle format for applications which allows for easy management of your web apps.
-    .
-    1: The health check happens trough checking if a port is opened. If your app doesn't open a port after 30 seconds it's presumed not healthy and gets a term signal.
 
 Homepage:            http://www.yesodweb.com/
 License:             MIT
