diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,33 @@
 
 ## Unreleased
 
+## [0.3.8] - 2020-06-03
+
+### Added
+
+- `cachix push --omit-deriver` if you'd like not to reveal Deriver field to Cachix
+
+### Changed
+
+- Retries are now exponential to offload the server a bit
+
+### Fixed
+
+- #308: Test failure due to dependency bump
+
+- Pretty print exceptions
+
+- Create nixos directory before checking if it's writable
+
+- A number of error messaging improvements:
+
+  * Don't suggest creating a cache when generating keypair as it's the wrong order
+
+  * #290: Explain what is going on when there's no signing key
+
+  * #262: improve instructions when on NixOS and the user is untrusted
+
+
 ## [0.3.7] - 2020-03-12
 
 ### Added
@@ -183,7 +210,10 @@
 
 - Initial release @domenkozar
 
-[Unreleased]: https://github.com/cachix/cachix/compare/v0.3.0...HEAD
+[Unreleased]: https://github.com/cachix/cachix/compare/v0.3.7...HEAD
+[0.3.7]: https://github.com/cachix/cachix/compare/v0.3.6...v0.3.7
+[0.3.6]: https://github.com/cachix/cachix/compare/v0.3.5...v0.3.6
+[0.3.5]: https://github.com/cachix/cachix/compare/v0.3.4...v0.3.5
 [0.3.4]: https://github.com/cachix/cachix/compare/v0.3.3...v0.3.4
 [0.3.3]: https://github.com/cachix/cachix/compare/v0.3.2...v0.3.3
 [0.3.2]: https://github.com/cachix/cachix/compare/v0.3.1...v0.3.2
diff --git a/cachix.cabal b/cachix.cabal
--- a/cachix.cabal
+++ b/cachix.cabal
@@ -1,9 +1,10 @@
 cabal-version:      2.2
 name:               cachix
-version: 0.3.7
+version: 0.3.8
 license:            Apache-2.0
 license-file:       LICENSE
 copyright:          2018 Domen Kožar
+category:           Nix
 maintainer:         domen@enlambda.com
 author:             Domen Kožar
 homepage:           https://github.com/cachix/cachix#readme
diff --git a/src/Cachix/Client/Commands.hs b/src/Cachix/Client/Commands.hs
--- a/src/Cachix/Client/Commands.hs
+++ b/src/Cachix/Client/Commands.hs
@@ -15,7 +15,7 @@
 import qualified Cachix.Api as Api
 import Cachix.Api.Error
 import Cachix.Client.Config
-  ( BinaryCacheConfig (..),
+  ( BinaryCacheConfig (BinaryCacheConfig),
     Config (..),
     mkConfig,
     writeConfig,
@@ -24,7 +24,7 @@
 import Cachix.Client.Env (Env (..))
 import Cachix.Client.Exception (CachixException (..))
 import Cachix.Client.HumanSize (humanSize)
-import Cachix.Client.InstallationMode
+import qualified Cachix.Client.InstallationMode as InstallationMode
 import qualified Cachix.Client.NixConf as NixConf
 import Cachix.Client.NixVersion (assertNixVersion)
 import Cachix.Client.OptionsParser
@@ -40,13 +40,11 @@
   )
 import Cachix.Client.Servant
 import qualified Cachix.Types.SigningKeyCreate as SigningKeyCreate
-import Control.Concurrent (threadDelay)
 import Control.Exception.Safe (handle, throwM)
 import Control.Retry (RetryStatus (rsIterNumber))
 import Crypto.Sign.Ed25519
 import qualified Data.ByteString.Base64 as B64
-import Data.List (isSuffixOf, reverse)
-import Data.Maybe (fromJust)
+import Data.List (isSuffixOf)
 import Data.String.Here
 import qualified Data.Text as T
 import Network.HTTP.Types (status401, status404)
@@ -58,20 +56,14 @@
 import System.Directory (doesFileExist)
 import System.Environment (lookupEnv)
 import System.FSNotify
-import System.IO (hIsTerminalDevice, stdin)
+import System.IO (hIsTerminalDevice)
 
 authtoken :: Env -> Text -> IO ()
 authtoken env token = do
   -- TODO: check that token actually authenticates!
   writeConfig (configPath (cachixoptions env)) $ case config env of
-    Just config -> config {authToken = Token (toS token)}
+    Just cfg -> cfg {authToken = Token (toS token)}
     Nothing -> mkConfig token
-  putStrLn
-    ( [hereLit|
-Continue by creating a binary cache at https://cachix.org
-  |] ::
-        Text
-    )
 
 create :: Env -> Text -> IO ()
 create _ _ =
@@ -79,7 +71,7 @@
 
 generateKeypair :: Env -> Text -> IO ()
 generateKeypair Env {config = Nothing} _ = throwIO $ NoConfig "Start with visiting https://cachix.org and copying the token to $ cachix authtoken <token>"
-generateKeypair env@Env {config = Just config} name = do
+generateKeypair env@Env {config = Just cfg} name = do
   (PublicKey pk, sk) <- createKeypair
   let signingKey = exportSigningKey $ SigningKey sk
       signingKeyCreate = SigningKeyCreate.SigningKeyCreate (toS $ B64.encode pk)
@@ -87,11 +79,11 @@
   -- we first validate if key can be added to the binary cache
   (_ :: NoContent) <-
     escalate <=< (`runClientM` clientenv env) $
-      Api.createKey (cachixBCClient name) (authToken config) signingKeyCreate
+      Api.createKey (cachixBCClient name) (authToken cfg) signingKeyCreate
   -- if key was successfully added, write it to the config
   -- TODO: warn if binary cache with the same key already exists
   writeConfig (configPath (cachixoptions env)) $
-    config {binaryCaches = binaryCaches config <> [bcc]}
+    cfg {binaryCaches = binaryCaches cfg <> [bcc]}
   putStrLn
     ( [iTrim|
 Secret signing key has been saved in the file above. To populate
@@ -125,7 +117,7 @@
 accessDeniedBinaryCache name =
   AccessDeniedBinaryCache $ "You don't seem to have API access to binary cache " <> name
 
-use :: Env -> Text -> UseOptions -> IO ()
+use :: Env -> Text -> InstallationMode.UseOptions -> IO ()
 use env name useOptions = do
   -- 1. get cache public key
   res <- (`runClientM` clientenv env) $ Api.get (cachixBCClient name) (envToToken env)
@@ -137,18 +129,18 @@
       | otherwise -> throwM err
     Right binaryCache -> do
       () <- escalateAs UnsupportedNixVersion =<< assertNixVersion
-      user <- getUser
+      user <- InstallationMode.getUser
       nc <- NixConf.read NixConf.Global
-      isTrusted <- isTrustedUser $ NixConf.readLines (catMaybes [nc]) NixConf.isTrustedUsers
+      isTrusted <- InstallationMode.isTrustedUser $ NixConf.readLines (catMaybes [nc]) NixConf.isTrustedUsers
       isNixOS <- doesFileExist "/etc/NIXOS"
       let nixEnv =
-            NixEnv
-              { isRoot = user == "root",
-                isTrusted = isTrusted,
-                isNixOS = isNixOS
+            InstallationMode.NixEnv
+              { InstallationMode.isRoot = user == "root",
+                InstallationMode.isTrusted = isTrusted,
+                InstallationMode.isNixOS = isNixOS
               }
-      addBinaryCache (config env) binaryCache useOptions $
-        fromMaybe (getInstallationMode nixEnv) (useMode useOptions)
+      InstallationMode.addBinaryCache (config env) binaryCache useOptions $
+        fromMaybe (InstallationMode.getInstallationMode nixEnv) (InstallationMode.useMode useOptions)
 
 -- TODO: lots of room for performance improvements
 push :: Env -> PushArguments -> IO ()
@@ -215,9 +207,30 @@
       maybeBCSK = case config env of
         Nothing -> Nothing
         Just c -> Config.secretKey <$> head (matches c)
-  -- TODO: better error msg
-  escalateAs FatalError $ parseSigningKeyLenient $ fromJust $ maybeBCSK <|> toS <$> maybeEnvSK <|> panic "You need to: export CACHIX_SIGNING_KEY=XXX"
+  signingKey <- case maybeBCSK <|> toS <$> maybeEnvSK of
+    Just key -> return key
+    Nothing -> throwIO $ NoSigningKey msg
+  escalateAs FatalError $ parseSigningKeyLenient signingKey
+  where
+    msg :: Text
+    msg =
+      [iTrim|
+Signing key not found. 
 
+It is generated by `cachix generate-keypair <name>` and stored in ~/config/cachix/cachix.dhall
+
+There are a few options why this happened:
+
+a) You haven't generated signing key yet for your cache 
+
+b) You have the key but you're pushing from a different machine. 
+   You can set it via $CACHIX_SIGNING_KEY environment variable.
+
+c) You've lost the signing key. In that case it's best to delete the cache and start again.
+   Note that everyone that configured the binary cache will have to do it again to set the new
+   public key.
+      |]
+
 retryText :: RetryStatus -> Text
 retryText retrystatus =
   if rsIterNumber retrystatus == 0
@@ -237,7 +250,8 @@
         -- we append newline instead of putStrLn due to https://github.com/haskell/text/issues/242
         putStr $ retryText retrystatus <> "compressing and pushing " <> storePath <> " (" <> humanSize (fromIntegral size) <> ")\n",
       onDone = pass,
-      withXzipCompressor = defaultWithXzipCompressorWithLevel (compressionLevel opts)
+      withXzipCompressor = defaultWithXzipCompressorWithLevel (compressionLevel opts),
+      Cachix.Client.Push.omitDeriver = Cachix.Client.OptionsParser.omitDeriver opts
     }
 
 pushStorePath :: Env -> PushOptions -> Text -> Text -> IO ()
diff --git a/src/Cachix/Client/Config.hs b/src/Cachix/Client/Config.hs
--- a/src/Cachix/Client/Config.hs
+++ b/src/Cachix/Client/Config.hs
@@ -14,7 +14,6 @@
 import Cachix.Client.Config.Orphans ()
 import Dhall hiding (Text)
 import Dhall.Pretty (prettyExpr)
-import GHC.Generics (Generic)
 import Protolude
 import Servant.Auth.Client
 import System.Directory
diff --git a/src/Cachix/Client/Env.hs b/src/Cachix/Client/Env.hs
--- a/src/Cachix/Client/Env.hs
+++ b/src/Cachix/Client/Env.hs
@@ -10,7 +10,6 @@
 import Cachix.Client.OptionsParser (CachixOptions (..))
 import Cachix.Client.Store (Store, openStore)
 import Cachix.Client.URI (getBaseUrl)
-import Control.Concurrent.Async (Async, async)
 import Data.Version (showVersion)
 import Network.HTTP.Client
   ( ManagerSettings,
@@ -38,15 +37,15 @@
   store <- async openStore
   -- make sure path to the config is passed as absolute to dhall logic
   canonicalConfigPath <- canonicalizePath (configPath rawcachixoptions)
-  let cachixoptions = rawcachixoptions {configPath = canonicalConfigPath}
-  config <- readConfig $ configPath cachixoptions
+  let cachixOptions = rawcachixoptions {configPath = canonicalConfigPath}
+  cfg <- readConfig $ configPath cachixOptions
   manager <- newTlsManagerWith customManagerSettings
-  let clientenv = mkClientEnv manager $ getBaseUrl (host cachixoptions)
+  let clientEnv = mkClientEnv manager $ getBaseUrl (host cachixOptions)
   return
     Env
-      { config = config,
-        clientenv = clientenv,
-        cachixoptions = cachixoptions,
+      { config = cfg,
+        clientenv = clientEnv,
+        cachixoptions = cachixOptions,
         storeAsync = store
       }
 
diff --git a/src/Cachix/Client/Exception.hs b/src/Cachix/Client/Exception.hs
--- a/src/Cachix/Client/Exception.hs
+++ b/src/Cachix/Client/Exception.hs
@@ -8,6 +8,7 @@
   | MustBeRoot Text
   | NixOSInstructions Text
   | AmbiguousInput Text
+  | NoSigningKey Text
   | NoInput Text
   | NoConfig Text
   | NetRcParseError Text
@@ -19,5 +20,17 @@
   deriving (Show, Typeable)
 
 instance Exception CachixException where
-  displayException (NixOSInstructions txt) = toS txt
-  displayException e = show e
+  displayException (UnsupportedNixVersion s) = toS s
+  displayException (UserEnvNotSet s) = toS s
+  displayException (MustBeRoot s) = toS s
+  displayException (NixOSInstructions s) = toS s
+  displayException (AmbiguousInput s) = toS s
+  displayException (NoInput s) = toS s
+  displayException (NoConfig s) = toS s
+  displayException (NoSigningKey s) = toS s
+  displayException (NetRcParseError s) = toS s
+  displayException (NarStreamingError _ s) = toS s
+  displayException (NarHashMismatch s) = toS s
+  displayException (DeprecatedCommand s) = toS s
+  displayException (AccessDeniedBinaryCache s) = toS s
+  displayException (BinaryCacheNotFound s) = toS s
diff --git a/src/Cachix/Client/InstallationMode.hs b/src/Cachix/Client/InstallationMode.hs
--- a/src/Cachix/Client/InstallationMode.hs
+++ b/src/Cachix/Client/InstallationMode.hs
@@ -13,7 +13,7 @@
   )
 where
 
-import Cachix.Api as Api
+import qualified Cachix.Api as Api
 import Cachix.Client.Config (Config)
 import Cachix.Client.Exception (CachixException (..))
 import qualified Cachix.Client.NetRc as NetRc
@@ -38,6 +38,7 @@
   = Install NixConf.NixConfLoc
   | WriteNixOS
   | UntrustedRequiresSudo
+  | UntrustedNixOS
   deriving (Show, Eq)
 
 data UseOptions
@@ -59,19 +60,49 @@
 toString (Install NixConf.Local) = "user-nixconf"
 toString WriteNixOS = "nixos"
 toString UntrustedRequiresSudo = "untrusted-requires-sudo"
+toString UntrustedNixOS = "untrusted-nixos"
 
 getInstallationMode :: NixEnv -> InstallationMode
 getInstallationMode nixenv
   | isNixOS nixenv && isRoot nixenv = WriteNixOS
   | not (isNixOS nixenv) && isRoot nixenv = Install NixConf.Global
   | isTrusted nixenv = Install NixConf.Local
+  | isNixOS nixenv = UntrustedNixOS
   | otherwise = UntrustedRequiresSudo
 
 -- | Add a Binary cache to nix.conf, print nixos config or fail
 addBinaryCache :: Maybe Config -> Api.BinaryCache -> UseOptions -> InstallationMode -> IO ()
-addBinaryCache _ _ _ UntrustedRequiresSudo =
+addBinaryCache _ _ _ UntrustedNixOS = do
+  user <- getUser
   throwIO $
-    MustBeRoot "Run command as root OR execute: $ echo \"trusted-users = root $USER\" | sudo tee -a /etc/nix/nix.conf && sudo pkill nix-daemon"
+    MustBeRoot
+      [i|This user doesn't have permissions to configure binary caches.
+
+You can either:
+
+a) Run the same command as root to write NixOS configuration.
+
+b) Add the following to your configuration.nix to add your user as trusted 
+   and then try again:
+
+  trustedUsers = [ "root" "${user}" ];
+
+    |]
+addBinaryCache _ _ _ UntrustedRequiresSudo = do
+  user <- getUser
+  throwIO $
+    MustBeRoot
+      [i|This user doesn't have permissions to configure binary caches.
+
+You can either:
+
+a) Run the same command as root to configure them globally.
+
+b) Run the following command to add your user as trusted 
+   and then try again:
+
+  echo "trusted-users = root ${user}" | sudo tee -a /etc/nix/nix.conf && sudo pkill nix-daemon
+    |]
 addBinaryCache maybeConfig bc useOptions WriteNixOS =
   nixosBinaryCache maybeConfig bc useOptions
 addBinaryCache maybeConfig bc _ (Install ncl) = do
@@ -84,7 +115,7 @@
         lnc <- NixConf.read NixConf.Local
         return ([gnc, lnc], lnc)
   let nixconf = fromMaybe (NixConf.NixConf []) output
-  netrcLocMaybe <- forM (guard $ not (isPublic bc)) $ const $ addPrivateBinaryCacheNetRC maybeConfig bc ncl
+  netrcLocMaybe <- forM (guard $ not (Api.isPublic bc)) $ const $ addPrivateBinaryCacheNetRC maybeConfig bc ncl
   let addNetRCLine :: NixConf.NixConf -> NixConf.NixConf
       addNetRCLine = fromMaybe identity $ do
         netrcLoc <- netrcLocMaybe :: Maybe FilePath
@@ -94,11 +125,12 @@
         pure (NixConf.setNetRC $ toS netrcLoc)
   NixConf.write ncl $ addNetRCLine $ NixConf.add bc (catMaybes input) nixconf
   filename <- NixConf.getFilename ncl
-  putStrLn $ "Configured " <> uri bc <> " binary cache in " <> toS filename
+  putStrLn $ "Configured " <> Api.uri bc <> " binary cache in " <> toS filename
 
 nixosBinaryCache :: Maybe Config -> Api.BinaryCache -> UseOptions -> IO ()
 nixosBinaryCache maybeConfig bc UseOptions {useNixOSFolder = baseDirectory} = do
-  eitherPermissions <- try $ getPermissions (toS baseDirectory) :: IO (Either SomeException Permissions)
+  _ <- try $ createDirectoryIfMissing True $ toS toplevel :: IO (Either SomeException ())
+  eitherPermissions <- try $ getPermissions (toS toplevel) :: IO (Either SomeException Permissions)
   case eitherPermissions of
     Left _ -> throwIO $ NixOSInstructions $ noEtcPermissionInstructions $ toS baseDirectory
     Right permissions
@@ -106,10 +138,9 @@
       | otherwise -> throwIO $ NixOSInstructions $ noEtcPermissionInstructions $ toS baseDirectory
   where
     installFiles = do
-      createDirectoryIfMissing True $ toS toplevel
       writeFile (toS glueModuleFile) glueModule
       writeFile (toS cacheModuleFile) cacheModule
-      unless (isPublic bc) $ void $ addPrivateBinaryCacheNetRC maybeConfig bc NixConf.Global
+      unless (Api.isPublic bc) $ void $ addPrivateBinaryCacheNetRC maybeConfig bc NixConf.Global
       putText instructions
     configurationNix :: Text
     configurationNix = toS $ toS baseDirectory </> "configuration.nix"
@@ -120,7 +151,7 @@
     glueModuleFile :: Text
     glueModuleFile = toplevel <> ".nix"
     cacheModuleFile :: Text
-    cacheModuleFile = toplevel <> "/" <> toS (name bc) <> ".nix"
+    cacheModuleFile = toplevel <> "/" <> toS (Api.name bc) <> ".nix"
     noEtcPermissionInstructions :: Text -> Text
     noEtcPermissionInstructions dir =
       [iTrim|
@@ -132,7 +163,7 @@
     instructions =
       [iTrim|
 Cachix configuration written to ${glueModuleFile}.
-Binary cache ${name bc} configuration written to ${cacheModuleFile}.
+Binary cache ${Api.name bc} configuration written to ${cacheModuleFile}.
 
 To start using cachix add the following to your ${configurationNix}:
 
@@ -164,10 +195,10 @@
 {
   nix = {
     binaryCaches = [
-      "${uri bc}"
+      "${Api.uri bc}"
     ];
     binaryCachePublicKeys = [
-      ${T.intercalate " " (map (\s -> "\"" <> s <> "\"") (publicSigningKeys bc))}
+      ${T.intercalate " " (map (\s -> "\"" <> s <> "\"") (Api.publicSigningKeys bc))}
     ];
   };
 }
@@ -190,12 +221,12 @@
   user <- getUser
   -- to detect single user installations
   permissions <- getPermissions "/nix/store"
-  let isTrusted = writable permissions || user `elem` users
-  when (not (null groups) && not isTrusted) $ do
+  let isTrustedU = writable permissions || user `elem` users
+  when (not (null groups) && not isTrustedU) $ do
     -- TODO: support Nix group syntax
     putText "Warn: cachix doesn't yet support checking if user is trusted via groups, so it will recommend sudo"
     putStrLn $ "Warn: groups found " <> T.intercalate "," groups
-  return isTrusted
+  return isTrustedU
   where
     groups = filter (\u -> T.head u == '@') users
 
diff --git a/src/Cachix/Client/NixConf.hs b/src/Cachix/Client/NixConf.hs
--- a/src/Cachix/Client/NixConf.hs
+++ b/src/Cachix/Client/NixConf.hs
@@ -32,7 +32,7 @@
   )
 where
 
-import Cachix.Api (BinaryCache (..))
+import qualified Cachix.Api as Api
 import Data.Char (isSpace)
 import Data.List (nub)
 import qualified Data.Text as T
@@ -85,14 +85,14 @@
 isTrustedUsers _ = Nothing
 
 -- | Pure version of addIO
-add :: BinaryCache -> [NixConf] -> NixConf -> NixConf
+add :: Api.BinaryCache -> [NixConf] -> NixConf -> NixConf
 add bc toRead toWrite =
   writeLines isPublicKey (TrustedPublicKeys $ nub publicKeys) $
     writeLines isSubstituter (Substituters $ nub substituters) toWrite
   where
     -- Note: some defaults are always appended since overriding some setttings in nix.conf overrides defaults otherwise
-    substituters = (defaultPublicURI : readLines toRead isSubstituter) <> [uri bc]
-    publicKeys = (defaultSigningKey : readLines toRead isPublicKey) <> publicSigningKeys bc
+    substituters = (defaultPublicURI : readLines toRead isSubstituter) <> [Api.uri bc]
+    publicKeys = (defaultSigningKey : readLines toRead isPublicKey) <> Api.publicSigningKeys bc
 
 defaultPublicURI :: Text
 defaultPublicURI = "https://cache.nixos.org"
diff --git a/src/Cachix/Client/OptionsParser.hs b/src/Cachix/Client/OptionsParser.hs
--- a/src/Cachix/Client/OptionsParser.hs
+++ b/src/Cachix/Client/OptionsParser.hs
@@ -11,7 +11,6 @@
 import qualified Cachix.Client.Config as Config
 import qualified Cachix.Client.InstallationMode as InstallationMode
 import Cachix.Client.URI (defaultCachixURI)
-import Data.Bifunctor (first)
 import Options.Applicative
 import Protolude hiding (option)
 import URI.ByteString
@@ -78,7 +77,8 @@
 data PushOptions
   = PushOptions
       { compressionLevel :: Int,
-        numJobs :: Int
+        numJobs :: Int,
+        omitDeriver :: Bool
       }
   deriving (Show)
 
@@ -119,6 +119,7 @@
               <> showDefault
               <> value 4
           )
+        <*> switch (long "omit-deriver" <> help "Do not publish which derivations built the store paths.")
     push = (\opts cache f -> Push $ f opts cache) <$> pushOptions <*> nameArg <*> (pushPaths <|> pushWatchStore)
     pushPaths =
       (\paths opts cache -> PushPaths opts cache paths)
diff --git a/src/Cachix/Client/Push.hs b/src/Cachix/Client/Push.hs
--- a/src/Cachix/Client/Push.hs
+++ b/src/Cachix/Client/Push.hs
@@ -30,7 +30,7 @@
 import qualified Control.Concurrent.QSem as QSem
 import Control.Exception.Safe (MonadMask, throwM)
 import Control.Monad.Trans.Resource (ResourceT)
-import Control.Retry (RetryPolicy, RetryStatus, constantDelay, limitRetries, recoverAll)
+import Control.Retry (RetryPolicy, RetryStatus, exponentialBackoff, limitRetries, recoverAll)
 import Crypto.Sign.Ed25519
 import qualified Data.ByteString.Base64 as B64
 import Data.Conduit
@@ -63,7 +63,8 @@
         on401 :: m r,
         onError :: ClientError -> m r,
         onDone :: m r,
-        withXzipCompressor :: forall a. (ConduitM ByteString ByteString (ResourceT IO) () -> m a) -> m a
+        withXzipCompressor :: forall a. (ConduitM ByteString ByteString (ResourceT IO) () -> m a) -> m a,
+        omitDeriver :: Bool
       }
 
 defaultWithXzipCompressor :: forall m a. (ConduitM ByteString ByteString (ResourceT IO) () -> m a) -> m a
@@ -142,7 +143,7 @@
             .| passthroughHashSinkB16 fileHashRef
     let subdomain =
           -- TODO: multipart
-          if (fromIntegral storePathSize / (1024 * 1024)) > 100
+          if (fromIntegral storePathSize / (1024 * 1024) :: Double) > 100
             then "api"
             else toS name
         newClientEnv =
@@ -165,7 +166,10 @@
       when (narHash /= toS narHashNix) $ throwM $ NarHashMismatch "Nar hash mismatch between nix-store --dump and nix db"
       fileHash <- readIORef fileHashRef
       fileSize <- readIORef fileSizeRef
-      deriver <- toS <$> Store.validPathInfoDeriver pathinfo
+      deriver <-
+        if omitDeriver cb
+          then pure Store.unknownDeriver
+          else toS <$> Store.validPathInfoDeriver pathinfo
       referencesPathSet <- Store.validPathInfoReferences pathinfo
       references <- sort <$> Store.traversePathSet (pure . toS) referencesPathSet
       let fp = fingerprint storePath narHash narSize references
@@ -180,7 +184,7 @@
                 Api.cFileHash = toS fileHash,
                 Api.cReferences = fmap (T.drop 11) references,
                 Api.cDeriver =
-                  if deriver == "unknown-deriver"
+                  if deriver == Store.unknownDeriver
                     then deriver
                     else T.drop 11 deriver,
                 Api.cSig = toS $ B64.encode $ unSignature sig
@@ -200,7 +204,7 @@
   where
     defaultRetryPolicy :: RetryPolicy
     defaultRetryPolicy =
-      constantDelay 50000 <> limitRetries 3
+      exponentialBackoff 100000 <> limitRetries 3
 
 -- | Push an entire closure
 --
diff --git a/src/Cachix/Client/Store.hs b/src/Cachix/Client/Store.hs
--- a/src/Cachix/Client/Store.hs
+++ b/src/Cachix/Client/Store.hs
@@ -15,6 +15,7 @@
     validPathInfoNarSize,
     validPathInfoNarHash,
     validPathInfoDeriver,
+    unknownDeriver,
     validPathInfoReferences,
 
     -- * Get closures
@@ -134,6 +135,8 @@
       |]
 
 -- | Deriver field of a ValidPathInfo struct. Source: store-api.hh
+--
+-- Returns 'unknownDeriver' when missing.
 validPathInfoDeriver :: ForeignPtr (Ref ValidPathInfo) -> IO ByteString
 validPathInfoDeriver vpi =
   unsafePackMallocCString
@@ -143,6 +146,11 @@
           return strdup((deriver == "" ? "unknown-deriver" : deriver->c_str()));
         }
       |]
+
+-- | String constant representing the case when the deriver of a store path does
+-- not exist or is not known. Value: @unknown-deriver@
+unknownDeriver :: Text
+unknownDeriver = "unknown-deriver"
 
 -- | References field of a ValidPathInfo struct. Source: store-api.hh
 validPathInfoReferences :: ForeignPtr (Ref ValidPathInfo) -> IO PathSet
diff --git a/test/InstallationModeSpec.hs b/test/InstallationModeSpec.hs
--- a/test/InstallationModeSpec.hs
+++ b/test/InstallationModeSpec.hs
@@ -15,22 +15,22 @@
               isNixOS = True
             }
      in getInstallationMode nixenv `shouldBe` WriteNixOS
-  it "NixOS without trust prints configuration plus trust" $
+  it "NixOS without trust prints steps to follow" $
     let nixenv =
           NixEnv
             { isTrusted = False,
               isRoot = False,
               isNixOS = True
             }
-     in getInstallationMode nixenv `shouldBe` UntrustedRequiresSudo
-  it "NixOS without trust prints configuration on older Nix" $
+     in getInstallationMode nixenv `shouldBe` UntrustedNixOS
+  it "NixOS without trust prints steps to follow" $
     let nixenv =
           NixEnv
             { isTrusted = False,
               isRoot = False,
               isNixOS = True
             }
-     in getInstallationMode nixenv `shouldBe` UntrustedRequiresSudo
+     in getInstallationMode nixenv `shouldBe` UntrustedNixOS
   it "NixOS non-root trusted results into local install" $
     let nixenv =
           NixEnv
diff --git a/test/NetRcSpec.hs b/test/NetRcSpec.hs
--- a/test/NetRcSpec.hs
+++ b/test/NetRcSpec.hs
@@ -37,11 +37,11 @@
 
 -- TODO: poor man's golden tests, use https://github.com/stackbuilders/hspec-golden
 test :: [BinaryCache] -> Text -> Expectation
-test binaryCaches goldenName = withSystemTempFile "hspec-netrc" $ \filepath _ -> do
+test caches goldenName = withSystemTempFile "hspec-netrc" $ \filepath _ -> do
   let input = "test/data/" <> toS goldenName <> ".input"
       output = "test/data/" <> toS goldenName <> ".output"
   copyFile input filepath
-  NetRc.add config binaryCaches filepath
+  NetRc.add config caches filepath
   real <- readFile filepath
   expected <- readFile output
   real `shouldBe` expected
diff --git a/test/NixVersionSpec.hs b/test/NixVersionSpec.hs
--- a/test/NixVersionSpec.hs
+++ b/test/NixVersionSpec.hs
@@ -15,11 +15,8 @@
   it "parses 'nix-env (Nix) 1.11.13' as Nix1XX" $
     parseNixVersion "nix-env (Nix) 1.11.13"
       `shouldBe` Left "Nix 2.0.2 or lower is not supported. Please upgrade: https://nixos.org/nix/"
-  it "parses 'nix-env (Nix) 2.0.5' as Nix201" $
-    parseNixVersion "nix-env (Nix) 2.0.5"
-      `shouldBe` Right ()
-  it "parses 'nix-env (Nix) 2.0.1pre6053_444b921' as Nix201" $
-    parseNixVersion "nix-env (Nix) 2.0.1pre6053_444b921"
+  it "parses 'nix-env (Nix) 2.0.2' as Nix202" $
+    parseNixVersion "nix-env (Nix) 2.0.2"
       `shouldBe` Right ()
   it "fails with unknown string 'foobar'" $
     parseNixVersion "foobar"
