diff --git a/nova/tests/unit/virt/test_block_device.py b/nova/tests/unit/virt/test_block_device.py
index 703f15967cba..3973b7fb5f40 100644
--- a/nova/tests/unit/virt/test_block_device.py
+++ b/nova/tests/unit/virt/test_block_device.py
@@ -15,6 +15,7 @@
 from os_brick import encryptors
 from unittest import mock
 
+import ddt
 from oslo_serialization import jsonutils
 from oslo_utils.fixture import uuidsentinel as uuids
 
@@ -35,6 +36,7 @@ from nova.volume import cinder
 ATTACHMENT_ID = uuids.attachment_id
 
 
+@ddt.ddt
 class TestDriverBlockDevice(test.NoDBTestCase):
     # os-brick>=5.1 now uses external file system locks instead of internal
     # locks so we need to set up locking
@@ -613,6 +615,7 @@ class TestDriverBlockDevice(test.NoDBTestCase):
             # First call to get() fails because the API isn't new enough.
             # So we fallback to the old call.
             self.volume_api.get.side_effect = [
+                exception.CinderAPIVersionNotAvailable(version='3.69'),
                 exception.CinderAPIVersionNotAvailable(version='3.48'),
                 fake_volume]
 
@@ -688,14 +691,17 @@ class TestDriverBlockDevice(test.NoDBTestCase):
 
         if include_shared_targets:
             self.volume_api.get.assert_called_once_with(
-                self.context, fake_volume['id'], microversion='3.48')
+                self.context, fake_volume['id'], microversion='3.69')
         else:
             # First call to get() fails because the API isn't new enough.
             # So we fallback to the old call.
             self.volume_api.get.assert_has_calls([
+                mock.call(self.context, fake_volume['id'],
+                          microversion='3.69'),
                 mock.call(self.context, fake_volume['id'],
                           microversion='3.48'),
-                mock.call(self.context, fake_volume['id'])])
+                mock.call(self.context, fake_volume['id'],
+                          microversion=None)])
 
         try:
             self.volume_api.check_availability_zone.assert_called_once_with(
@@ -1557,6 +1563,24 @@ class TestDriverBlockDevice(test.NoDBTestCase):
         self._test_boot_from_volume_source_snapshot_volume_type(
             bdm, 'fake-lvm-1')
 
+    @ddt.data(['3.69'], ['3.69', '3.48'], ['3.69', '3.48', None])
+    def test__get_volume(self, microversions):
+        volume_api = mock.Mock()
+        exp = mock.Mock()
+        exc = exception.CinderAPIVersionNotAvailable
+        side_effect = [exc(version=mv) for mv in microversions[:-1]] + [exp]
+        volume_api.get.side_effect = side_effect
+
+        res = self.driver_classes['volume']._get_volume(
+            self.context, volume_api, mock.sentinel.volume_id)
+
+        self.assertEqual(exp, res)
+
+        self.assertEqual(len(microversions), volume_api.get.call_count)
+        volume_api.get.assert_has_calls(
+            [mock.call(self.context, mock.sentinel.volume_id, microversion=mv)
+             for mv in microversions])
+
 
 class TestDriverBlockDeviceNewFlow(TestDriverBlockDevice):
     """Virt block_device tests for the Cinder 3.44 volume attach flow
diff --git a/nova/virt/block_device.py b/nova/virt/block_device.py
index 28a866a817fb..059131c25095 100644
--- a/nova/virt/block_device.py
+++ b/nova/virt/block_device.py
@@ -399,13 +399,14 @@ class DriverVolumeBlockDevice(DriverBlockDevice):
 
     @staticmethod
     def _get_volume(context, volume_api, volume_id):
-        # First try to get the volume at microversion 3.48 so we can get the
-        # shared_targets parameter exposed in that version. If that API version
-        # is not available, we just fallback.
-        try:
-            return volume_api.get(context, volume_id, microversion='3.48')
-        except exception.CinderAPIVersionNotAvailable:
-            return volume_api.get(context, volume_id)
+        # First try microversion for tri-state shared_targets, then older
+        # shared_targets, finally fallback to standard v3.
+        versions = ('3.69', '3.48', None)
+        for mv in versions:
+            try:
+                return volume_api.get(context, volume_id, microversion=mv)
+            except exception.CinderAPIVersionNotAvailable:
+                pass
 
     def _create_volume(self, context, instance, volume_api, size,
                        wait_func=None, **create_kwargs):
diff --git a/releasenotes/notes/nvmeof-guard-0f99effdd03983b6.yaml b/releasenotes/notes/nvmeof-guard-0f99effdd03983b6.yaml
new file mode 100644
index 000000000000..379ae9daace3
--- /dev/null
+++ b/releasenotes/notes/nvmeof-guard-0f99effdd03983b6.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+  - |
+    `Bug #2035375 <https://bugs.launchpad.net/nova/+bug/2035375>`_: Fixed
+    leftover NVMe-oF subsystems when disconnecting multiple NVMe-oF volumes on
+    the same host from storage sharing the subsystem for different volumes.