diff --git a/src/libexpr/flake/flakeref.cc b/src/libexpr/flake/flakeref.cc
index 7631cd53a..253442566 100644
--- a/src/libexpr/flake/flakeref.cc
+++ b/src/libexpr/flake/flakeref.cc
@@ -145,10 +145,10 @@ FlakeRef::FlakeRef(const std::string & uri_, bool allowRelative)
             d.path = absPath(uri);
             try {
                 if (!S_ISDIR(lstat(d.path).st_mode))
-                    throw BadFlakeRef("path '%s' is not a flake (sub)directory");
+                    throw MissingFlake("path '%s' is not a flake (sub)directory", d.path);
             } catch (SysError & e) {
                 if (e.errNo == ENOENT || e.errNo == EISDIR)
-                    throw BadFlakeRef("flake '%s' does not exist");
+                    throw MissingFlake("flake '%s' does not exist", d.path);
                 throw;
             }
             while (true) {
@@ -156,7 +156,7 @@ FlakeRef::FlakeRef(const std::string & uri_, bool allowRelative)
                 subdir = baseNameOf(d.path) + (subdir.empty() ? "" : "/" + subdir);
                 d.path = dirOf(d.path);
                 if (d.path == "/")
-                    throw BadFlakeRef("path '%s' does not reference a Git repository", uri);
+                    throw MissingFlake("path '%s' is not a flake (because it does not reference a Git repository)", uri);
             }
         } else
             d.path = canonPath(uri);
diff --git a/src/libexpr/flake/flakeref.hh b/src/libexpr/flake/flakeref.hh
index 082dd8c26..9ddc227bb 100644
--- a/src/libexpr/flake/flakeref.hh
+++ b/src/libexpr/flake/flakeref.hh
@@ -187,6 +187,7 @@ struct FlakeRef
 std::ostream & operator << (std::ostream & str, const FlakeRef & flakeRef);
 
 MakeError(BadFlakeRef, Error);
+MakeError(MissingFlake, BadFlakeRef);
 
 std::optional<FlakeRef> parseFlakeRef(
     const std::string & uri, bool allowRelative = false);
diff --git a/src/nix/installables.cc b/src/nix/installables.cc
index dbbf58861..a4726a59e 100644
--- a/src/nix/installables.cc
+++ b/src/nix/installables.cc
@@ -417,25 +417,43 @@ std::vector<std::shared_ptr<Installable>> SourceExprCommand::parseInstallables(
                         Strings{"legacyPackages." + std::string(s, 8)}));
             }
 
-            else if (auto flakeRef = parseFlakeRef(s, true))
-                result.push_back(std::make_shared<InstallableFlake>(*this, std::move(*flakeRef),
-                        getDefaultFlakeAttrPaths()));
+            else {
 
-            else if ((colon = s.rfind(':')) != std::string::npos) {
-                auto flakeRef = std::string(s, 0, colon);
-                auto attrPath = std::string(s, colon + 1);
-                result.push_back(std::make_shared<InstallableFlake>(
-                        *this,
-                        FlakeRef(flakeRef, true),
-                        attrPath,
-                        getDefaultFlakeAttrPathPrefixes()));
+                std::exception_ptr flakeEx;
+
+                try {
+                    auto flakeRef = FlakeRef(s, true);
+                    result.push_back(std::make_shared<InstallableFlake>(
+                            *this, std::move(flakeRef), getDefaultFlakeAttrPaths()));
+                    continue;
+                } catch (MissingFlake &) {
+                    /* 's' could be parsed as a flakeref, but it
+                       references a local path that is not a flake. So
+                       take note of that. */
+                    flakeEx = std::current_exception();
+                } catch (BadFlakeRef &) {
+                }
+
+                if ((colon = s.rfind(':')) != std::string::npos) {
+                    auto flakeRef = std::string(s, 0, colon);
+                    auto attrPath = std::string(s, colon + 1);
+                    result.push_back(std::make_shared<InstallableFlake>(
+                            *this,
+                            FlakeRef(flakeRef, true),
+                            attrPath,
+                            getDefaultFlakeAttrPathPrefixes()));
+                }
+
+                else if (s.find('/') != std::string::npos && (storePath = follow(s)))
+                    result.push_back(std::make_shared<InstallableStorePath>(*storePath));
+
+                else {
+                    if (flakeEx)
+                        std::rethrow_exception(flakeEx);
+                    else
+                        throw Error("unsupported argument '%s'", s);
+                }
             }
-
-            else if (s.find('/') != std::string::npos && (storePath = follow(s)))
-                result.push_back(std::make_shared<InstallableStorePath>(*storePath));
-
-            else
-                throw Error("unsupported argument '%s'", s);
         }
     }