diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,8 @@
 # Release history for select-rpms
 
+## 0.3.0 (2025-06-04)
+- ExistingStrategy: add ExistingError which aborts for existing installed pkg
+
 ## 0.2.0 (2024-12-01)
 - extend ExistingStrategy with ExistingOnly
 - use sudoLog with --debug, falling back to old sudo_
diff --git a/select-rpms.cabal b/select-rpms.cabal
--- a/select-rpms.cabal
+++ b/select-rpms.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.2
 name:                select-rpms
-version:             0.2.0
+version:             0.3.0
 synopsis:            Select a subset of RPM packages
 description:
         A library for selecting a subset of RPM (sub)packages.
@@ -8,7 +8,7 @@
 license-file:        LICENSE
 author:              Jens Petersen <juhpetersen@gmail.com>
 maintainer:          Jens Petersen <juhpetersen@gmail.com>
-copyright:           2024  Jens Petersen <juhpetersen@gmail.com>
+copyright:           2024-2025  Jens Petersen <juhpetersen@gmail.com>
 category:            Distribution
 homepage:            https://github.com/juhp/select-rpms
 bug-reports:         https://github.com/juhp/select-rpms/issues
@@ -19,8 +19,9 @@
                       || == 9.0.2
                       || == 9.2.8
                       || == 9.4.8
-                      || == 9.6.6
-                      || == 9.8.2
+                      || == 9.6.7
+                      || == 9.8.4
+                      || == 9.10.2
 
 source-repository head
   type:                git
diff --git a/src/SelectRPMs.hs b/src/SelectRPMs.hs
--- a/src/SelectRPMs.hs
+++ b/src/SelectRPMs.hs
@@ -22,7 +22,10 @@
 
 import Control.Monad.Extra (forM_, mapMaybeM, unless, when)
 import Data.Either (partitionEithers)
-import Data.List.Extra (foldl', isInfixOf, nubOrd, nubSort, sort,
+import Data.List.Extra (isInfixOf, nubOrd, nubSort, sort,
+#if !MIN_VERSION_base(4,20,0)
+                        foldl',
+#endif
 #if MIN_VERSION_extra(1,7,11)
                         groupOnKey,
 #endif
@@ -123,15 +126,18 @@
 -- default update
 --
 -- The default strategy is to select existing subpackages, otherwise all.
-data ExistingStrategy = ExistingNoReinstall | ExistingSkip | ExistingOnly
+--
+-- The constructors are only really needed internally but exported for
+-- documentation.
+data ExistingStrategy = ExistingNoReinstall | ExistingSkip | ExistingOnly | ExistingError
   deriving Eq
 
 existingStrategyOption :: Parser ExistingStrategy
 existingStrategyOption =
   flagWith' ExistingNoReinstall 'N' "no-reinstall" "Do not reinstall existing NVRs" <|>
   flagWith' ExistingSkip 'S' "skip-existing" "Ignore already installed subpackages (implies --no-reinstall)" <|>
-  flagWith' ExistingOnly 'O' "only-existing" "Only update existing installed subpackages"
-
+  flagWith' ExistingOnly 'O' "only-existing" "Only update existing installed subpackages" <|>
+  flagWith' ExistingError 'E' "error-existing" "Abort for existing installed subpackages"
 
 -- | sets prompt default behaviour for yes/no questions
 data Yes = No | Yes
@@ -190,6 +196,7 @@
           Just ExistingSkip | existence /= NotInstalled -> Nothing
           Just ExistingNoReinstall | existence == ExistingNVR -> Nothing
           Just ExistingOnly | existence == NotInstalled -> Nothing
+          Just ExistingError | existence /= NotInstalled -> error' $ "aborting:" +-+ rpmName nvra +-+ "already installed"
           _ -> Just (existence, nvra)
 
 -- FIXME move to submodule?
