diff --git a/src/libstore/binary-cache-store.cc b/src/libstore/binary-cache-store.cc
index 8e6f1f55d715f32ed29afd38e37b485fce9ea7a3..7e3e5ff8847c909e0fbb134a13368f800018d4e6 100644
--- a/src/libstore/binary-cache-store.cc
+++ b/src/libstore/binary-cache-store.cc
@@ -296,7 +296,7 @@ void BinaryCacheStore::narFromPath(const Path & storePath, Sink & sink)
 }
 
 void BinaryCacheStore::queryPathInfoUncached(const Path & storePath,
-    Callback<std::shared_ptr<ValidPathInfo>> callback) noexcept
+    Callback<std::shared_ptr<const ValidPathInfo>> callback) noexcept
 {
     auto uri = getUri();
     auto act = std::make_shared<Activity>(*logger, lvlTalkative, actQueryPathInfo,
diff --git a/src/libstore/binary-cache-store.hh b/src/libstore/binary-cache-store.hh
index c772922949a386b80058ad5aa9242e59678537da..2d7cd1947bf27c2223d17857a519a0e91357cd29 100644
--- a/src/libstore/binary-cache-store.hh
+++ b/src/libstore/binary-cache-store.hh
@@ -74,7 +74,7 @@ public:
     bool isValidPathUncached(const Path & path) override;
 
     void queryPathInfoUncached(const Path & path,
-        Callback<std::shared_ptr<ValidPathInfo>> callback) noexcept override;
+        Callback<std::shared_ptr<const ValidPathInfo>> callback) noexcept override;
 
     Path queryPathFromHashPart(const string & hashPart) override
     { unsupported("queryPathFromHashPart"); }
diff --git a/src/libstore/legacy-ssh-store.cc b/src/libstore/legacy-ssh-store.cc
index d5fbdd25aa47d5a5ecfec5bf60fbb29d5ccc9611..1b8b5908cfadc8f69b8b9eb3aa2a5c1a0d1b2c9f 100644
--- a/src/libstore/legacy-ssh-store.cc
+++ b/src/libstore/legacy-ssh-store.cc
@@ -88,7 +88,7 @@ struct LegacySSHStore : public Store
     }
 
     void queryPathInfoUncached(const Path & path,
-        Callback<std::shared_ptr<ValidPathInfo>> callback) noexcept override
+        Callback<std::shared_ptr<const ValidPathInfo>> callback) noexcept override
     {
         try {
             auto conn(connections->get());
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc
index 49061f27d1375d2e1939bf5081abfed5a2255615..6bbe5433ce51c5e5c2363c6c53a02ad3aaf492f5 100644
--- a/src/libstore/local-store.cc
+++ b/src/libstore/local-store.cc
@@ -632,7 +632,7 @@ uint64_t LocalStore::addValidPath(State & state,
 
 
 void LocalStore::queryPathInfoUncached(const Path & path,
-    Callback<std::shared_ptr<ValidPathInfo>> callback) noexcept
+    Callback<std::shared_ptr<const ValidPathInfo>> callback) noexcept
 {
     try {
         auto info = std::make_shared<ValidPathInfo>();
diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh
index 77253fa4a4a8f30ef9e64d38d8fafffb357bb1c7..5aa6b0519640b762dbb73f756245d73139a18648 100644
--- a/src/libstore/local-store.hh
+++ b/src/libstore/local-store.hh
@@ -127,7 +127,7 @@ public:
     PathSet queryAllValidPaths() override;
 
     void queryPathInfoUncached(const Path & path,
-        Callback<std::shared_ptr<ValidPathInfo>> callback) noexcept override;
+        Callback<std::shared_ptr<const ValidPathInfo>> callback) noexcept override;
 
     void queryReferrers(const Path & path, PathSet & referrers) override;
 
diff --git a/src/libstore/misc.cc b/src/libstore/misc.cc
index 05b93d4c9b007ec22ac1ad1f17ea32f4c80856c9..2fceb9b9ac3124f0e221dde1c74d194322840fcb 100644
--- a/src/libstore/misc.cc
+++ b/src/libstore/misc.cc
@@ -33,7 +33,7 @@ void Store::computeFSClosure(const PathSet & startPaths,
             state->pending++;
         }
 
-        queryPathInfo(path, {[&, path](std::future<ref<ValidPathInfo>> fut) {
+        queryPathInfo(path, {[&, path](std::future<ref<const ValidPathInfo>> fut) {
             // FIXME: calls to isValidPath() should be async
 
             try {
diff --git a/src/libstore/nar-info-disk-cache.cc b/src/libstore/nar-info-disk-cache.cc
index 32ad7f2b27ffb2ee81145a22733ca8783f04c611..5bf9821958579e4602e3b7028851b7f713cdaeb0 100644
--- a/src/libstore/nar-info-disk-cache.cc
+++ b/src/libstore/nar-info-disk-cache.cc
@@ -219,7 +219,7 @@ public:
 
     void upsertNarInfo(
         const std::string & uri, const std::string & hashPart,
-        std::shared_ptr<ValidPathInfo> info) override
+        std::shared_ptr<const ValidPathInfo> info) override
     {
         retrySQLite<void>([&]() {
             auto state(_state.lock());
@@ -228,7 +228,7 @@ public:
 
             if (info) {
 
-                auto narInfo = std::dynamic_pointer_cast<NarInfo>(info);
+                auto narInfo = std::dynamic_pointer_cast<const NarInfo>(info);
 
                 assert(hashPart == storePathToHash(info->path));
 
diff --git a/src/libstore/nar-info-disk-cache.hh b/src/libstore/nar-info-disk-cache.hh
index 88d909732dbc4d67e42b9aa2d63b43d5292e8375..11e6c55ca9c6de4dfde54151bc2d25c07bb642fd 100644
--- a/src/libstore/nar-info-disk-cache.hh
+++ b/src/libstore/nar-info-disk-cache.hh
@@ -21,7 +21,7 @@ public:
 
     virtual void upsertNarInfo(
         const std::string & uri, const std::string & hashPart,
-        std::shared_ptr<ValidPathInfo> info) = 0;
+        std::shared_ptr<const ValidPathInfo> info) = 0;
 };
 
 /* Return a singleton cache object that can be used concurrently by
diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc
index f34369d8fe0ac73d89b2bf1adc78e4d8ebe8c875..2a89b7c98dcbae954aeadf406eae194d108974fb 100644
--- a/src/libstore/remote-store.cc
+++ b/src/libstore/remote-store.cc
@@ -350,7 +350,7 @@ void RemoteStore::querySubstitutablePathInfos(const PathSet & paths,
 
 
 void RemoteStore::queryPathInfoUncached(const Path & path,
-    Callback<std::shared_ptr<ValidPathInfo>> callback) noexcept
+    Callback<std::shared_ptr<const ValidPathInfo>> callback) noexcept
 {
     try {
         std::shared_ptr<ValidPathInfo> info;
diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh
index 1f375dd71520c19ba54b1708bb987c4e709ec82d..84de4c4601c5c1a3c9329fe0fcc2496c72e34250 100644
--- a/src/libstore/remote-store.hh
+++ b/src/libstore/remote-store.hh
@@ -43,7 +43,7 @@ public:
     PathSet queryAllValidPaths() override;
 
     void queryPathInfoUncached(const Path & path,
-        Callback<std::shared_ptr<ValidPathInfo>> callback) noexcept override;
+        Callback<std::shared_ptr<const ValidPathInfo>> callback) noexcept override;
 
     void queryReferrers(const Path & path, PathSet & referrers) override;
 
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index 1a1b24e3b0c69b340cb8e59904aa15891ee9ca69..54430d3baac5775fca6508e368fae2e31f003fc6 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -320,10 +320,10 @@ bool Store::isValidPathUncached(const Path & path)
 
 ref<const ValidPathInfo> Store::queryPathInfo(const Path & storePath)
 {
-    std::promise<ref<ValidPathInfo>> promise;
+    std::promise<ref<const ValidPathInfo>> promise;
 
     queryPathInfo(storePath,
-        {[&](std::future<ref<ValidPathInfo>> result) {
+        {[&](std::future<ref<const ValidPathInfo>> result) {
             try {
                 promise.set_value(result.get());
             } catch (...) {
@@ -336,7 +336,7 @@ ref<const ValidPathInfo> Store::queryPathInfo(const Path & storePath)
 
 
 void Store::queryPathInfo(const Path & storePath,
-    Callback<ref<ValidPathInfo>> callback) noexcept
+    Callback<ref<const ValidPathInfo>> callback) noexcept
 {
     std::string hashPart;
 
@@ -351,7 +351,7 @@ void Store::queryPathInfo(const Path & storePath,
                 stats.narInfoReadAverted++;
                 if (!*res)
                     throw InvalidPath(format("path '%s' is not valid") % storePath);
-                return callback(ref<ValidPathInfo>(*res));
+                return callback(ref<const ValidPathInfo>(*res));
             }
         }
 
@@ -367,7 +367,7 @@ void Store::queryPathInfo(const Path & storePath,
                         (res.second->path != storePath && storePathToName(storePath) != ""))
                         throw InvalidPath(format("path '%s' is not valid") % storePath);
                 }
-                return callback(ref<ValidPathInfo>(res.second));
+                return callback(ref<const ValidPathInfo>(res.second));
             }
         }
 
@@ -376,7 +376,7 @@ void Store::queryPathInfo(const Path & storePath,
     auto callbackPtr = std::make_shared<decltype(callback)>(std::move(callback));
 
     queryPathInfoUncached(storePath,
-        {[this, storePath, hashPart, callbackPtr](std::future<std::shared_ptr<ValidPathInfo>> fut) {
+        {[this, storePath, hashPart, callbackPtr](std::future<std::shared_ptr<const ValidPathInfo>> fut) {
 
             try {
                 auto info = fut.get();
@@ -396,7 +396,7 @@ void Store::queryPathInfo(const Path & storePath,
                     throw InvalidPath("path '%s' is not valid", storePath);
                 }
 
-                (*callbackPtr)(ref<ValidPathInfo>(info));
+                (*callbackPtr)(ref<const ValidPathInfo>(info));
             } catch (...) { callbackPtr->rethrow(); }
         }});
 }
@@ -418,7 +418,7 @@ PathSet Store::queryValidPaths(const PathSet & paths, SubstituteFlag maybeSubsti
 
     auto doQuery = [&](const Path & path ) {
         checkInterrupt();
-        queryPathInfo(path, {[path, &state_, &wakeup](std::future<ref<ValidPathInfo>> fut) {
+        queryPathInfo(path, {[path, &state_, &wakeup](std::future<ref<const ValidPathInfo>> fut) {
             auto state(state_.lock());
             try {
                 auto info = fut.get();
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 115b23cbf747ea3eabb8bb9dcf4c5131260b6268..e9e6e0dd2a84701fee2c60b5796116d7a05edcec 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -258,7 +258,7 @@ protected:
 
     struct State
     {
-        LRUCache<std::string, std::shared_ptr<ValidPathInfo>> pathInfoCache;
+        LRUCache<std::string, std::shared_ptr<const ValidPathInfo>> pathInfoCache;
     };
 
     Sync<State> state;
@@ -361,12 +361,12 @@ public:
 
     /* Asynchronous version of queryPathInfo(). */
     void queryPathInfo(const Path & path,
-        Callback<ref<ValidPathInfo>> callback) noexcept;
+        Callback<ref<const ValidPathInfo>> callback) noexcept;
 
 protected:
 
     virtual void queryPathInfoUncached(const Path & path,
-        Callback<std::shared_ptr<ValidPathInfo>> callback) noexcept = 0;
+        Callback<std::shared_ptr<const ValidPathInfo>> callback) noexcept = 0;
 
 public: