diff --git a/app/models/project.rb b/app/models/project.rb
index ab19190385e0304fe6ec090e5f16a1ea9ce7f947..4d1917b9ab2e9c4fe3a5532d8e19301d4373efe9 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1964,7 +1964,7 @@ class Project < ActiveRecord::Base
   end
 
   def migrate_to_hashed_storage!
-    return if hashed_storage?(:repository)
+    return unless storage_upgradable?
 
     update!(repository_read_only: true)
 
diff --git a/changelogs/unreleased/53700-hashed-storagemigration.yml b/changelogs/unreleased/53700-hashed-storagemigration.yml
new file mode 100644
index 0000000000000000000000000000000000000000..899012ffd22d69036a9a1c80de204a4a1dbbfd05
--- /dev/null
+++ b/changelogs/unreleased/53700-hashed-storagemigration.yml
@@ -0,0 +1,5 @@
+---
+title: 'Hashed Storage: allow migration to be retried in partially migrated projects'
+merge_request: 23087
+author:
+type: fixed
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index bdff68cee8b7fcb30490b2edbe1166eecb69fbbf..51278836604196a489898db3f4436f45ec2fb321 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -3087,6 +3087,14 @@ describe Project do
       it 'does not flag as read-only' do
         expect { project.migrate_to_hashed_storage! }.not_to change { project.repository_read_only }
       end
+
+      context 'when partially migrated' do
+        it 'returns true' do
+          project = create(:project, storage_version: 1, skip_disk_validation: true)
+
+          expect(project.migrate_to_hashed_storage!).to be_truthy
+        end
+      end
     end
   end