diff --git a/cabal-install/src/Distribution/Client/CmdInstall.hs b/cabal-install/src/Distribution/Client/CmdInstall.hs
index a154eff3ce9aa70586df7972e20e190631e09497..1144ff79613b35d1687d179bd327aabb0b2898c3 100644
--- a/cabal-install/src/Distribution/Client/CmdInstall.hs
+++ b/cabal-install/src/Distribution/Client/CmdInstall.hs
@@ -540,7 +540,7 @@ installAction flags@NixStyleFlags{extraFlags, configFlags, installFlags, project
         -- BuildOutcomes because we also need the component names
           traverseInstall (installCheckUnitExes InstallCheckInstall) installCfg
   where
-    configFlags' = disableTestsBenchsByDefault configFlags
+    configFlags' = disableTestsBenchsByDefault . ignoreProgramAffixes $ configFlags
     verbosity = fromFlagOrDefault normal (setupVerbosity $ configCommonFlags configFlags')
     ignoreProject = flagIgnoreProject projectFlags
     cliConfig =
@@ -1101,6 +1101,18 @@ disableTestsBenchsByDefault configFlags =
     , configBenchmarks = Flag False <> configBenchmarks configFlags
     }
 
+-- | Disables program prefix and suffix, in order to get the /canonical/
+-- executable name in the store and thus:
+--
+-- * avoid making the package hash depend on these options and needless rebuild;
+-- * provide the correct executable path to the install methods (copy, symlink).
+ignoreProgramAffixes :: ConfigFlags -> ConfigFlags
+ignoreProgramAffixes configFlags =
+  configFlags
+    { configProgPrefix = NoFlag
+    , configProgSuffix = NoFlag
+    }
+
 -- | Prepares a record containing the information needed to either symlink or
 -- copy an executable.
 symlink :: OverwritePolicy -> InstallExe -> UnitId -> UnqualComponentName -> Symlink
diff --git a/cabal-testsuite/PackageTests/Install/ProgramAffixes/Main.hs b/cabal-testsuite/PackageTests/Install/ProgramAffixes/Main.hs
new file mode 100644
index 0000000000000000000000000000000000000000..76a9bdb5d48831da2e59c811ecbcbb5a379bdfb5
--- /dev/null
+++ b/cabal-testsuite/PackageTests/Install/ProgramAffixes/Main.hs
@@ -0,0 +1 @@
+main = pure ()
diff --git a/cabal-testsuite/PackageTests/Install/ProgramAffixes/cabal.project b/cabal-testsuite/PackageTests/Install/ProgramAffixes/cabal.project
new file mode 100644
index 0000000000000000000000000000000000000000..e6fdbadb4398bc0e333947b5fb8021778310d943
--- /dev/null
+++ b/cabal-testsuite/PackageTests/Install/ProgramAffixes/cabal.project
@@ -0,0 +1 @@
+packages: .
diff --git a/cabal-testsuite/PackageTests/Install/ProgramAffixes/cabal.test.hs b/cabal-testsuite/PackageTests/Install/ProgramAffixes/cabal.test.hs
new file mode 100644
index 0000000000000000000000000000000000000000..c02eda531f6b5093cb59231e2c18fccbe47da27d
--- /dev/null
+++ b/cabal-testsuite/PackageTests/Install/ProgramAffixes/cabal.test.hs
@@ -0,0 +1,27 @@
+import Test.Cabal.Prelude
+import Data.Foldable (traverse_)
+
+-- Test that program affixes options result in successful installation:
+-- • Valid symlinks (--install-method=symlink)
+-- • Valid copy of executables (--install-method=copy)
+main = cabalTest $ do
+  env <- getTestEnv
+  recordMode DoNotRecord $ do
+    let installdir = testPrefixDir env </> "bin"
+        commonOpts = ["p", "--installdir", installdir, "--overwrite-policy=always"]
+        testAllAffixes installMethod = do
+          let testAffixes' = testAffixes
+                (commonOpts ++ ["--install-method", installMethod])
+          testAffixes' Nothing Nothing
+          testAffixes' (Just "a-") Nothing
+          testAffixes' Nothing (Just "-z")
+          testAffixes' (Just "a-") (Just "-z")
+    traverse_ testAllAffixes ["symlink", "copy"]
+  where
+    mkAffixOption option = maybe [] (\a -> ["--program-" ++ option, a])
+    mkProgramName p s = maybe [] id p ++ "p" ++ maybe [] id s
+    testAffixes commonOpts prefix suffix = do
+      cabal "install" (  commonOpts
+                      ++ mkAffixOption "prefix" prefix
+                      ++ mkAffixOption "suffix" suffix)
+      runInstalledExe (mkProgramName prefix suffix) []
diff --git a/cabal-testsuite/PackageTests/Install/ProgramAffixes/p.cabal b/cabal-testsuite/PackageTests/Install/ProgramAffixes/p.cabal
new file mode 100644
index 0000000000000000000000000000000000000000..30428ef4ac345b705abc6cbcaa7922977af06a3a
--- /dev/null
+++ b/cabal-testsuite/PackageTests/Install/ProgramAffixes/p.cabal
@@ -0,0 +1,8 @@
+name: p
+version: 1.0
+build-type: Simple
+cabal-version: >= 1.2
+
+executable p
+  main-is: Main.hs
+  build-depends: base
diff --git a/changelog.d/issue-9919 b/changelog.d/issue-9919
new file mode 100644
index 0000000000000000000000000000000000000000..a4fe32bbdefe861617b5467eb9d32ed69551587c
--- /dev/null
+++ b/changelog.d/issue-9919
@@ -0,0 +1,4 @@
+synopsis: Fix --program-suffix resulting in invalid installation
+packages: cabal-install
+issues: #8823 #9919
+prs: #10056