diff --git a/doc/whats-new.rst b/doc/whats-new.rst
index 05bdfcf78bb..e88faee2a43 100644
--- a/doc/whats-new.rst
+++ b/doc/whats-new.rst
@@ -48,6 +48,8 @@ Bug fixes
 - Many bugs fixed by the explicit indexes refactor, mainly related to multi-index (virtual)
   coordinates. See the corresponding pull-request on GitHub for more details. (:pull:`5692`).
   By `BenoƮt Bovy <https://github.com/benbovy>`_.
+- Fixed "unhashable type" error trying to read NetCDF file with variable having its 'units'
+  attribute not ``str`` (e.g. ``numpy.ndarray``) (:issue:`6368`). By `Oleh Khoma <https://github.com/okhoma>`_.
 
 Documentation
 ~~~~~~~~~~~~~
diff --git a/xarray/coding/times.py b/xarray/coding/times.py
index 0eb8707f0cc..42a815300e5 100644
--- a/xarray/coding/times.py
+++ b/xarray/coding/times.py
@@ -695,7 +695,8 @@ def encode(self, variable, name=None):
     def decode(self, variable, name=None):
         dims, data, attrs, encoding = unpack_for_decoding(variable)
 
-        if "units" in attrs and attrs["units"] in TIME_UNITS:
+        units = attrs.get("units")
+        if isinstance(units, str) and units in TIME_UNITS:
             units = pop_to(attrs, encoding, "units")
             transform = partial(decode_cf_timedelta, units=units)
             dtype = np.dtype("timedelta64[ns]")
diff --git a/xarray/tests/test_conventions.py b/xarray/tests/test_conventions.py
index ab290955e6c..83e560e7208 100644
--- a/xarray/tests/test_conventions.py
+++ b/xarray/tests/test_conventions.py
@@ -416,3 +416,10 @@ def test_encoding_kwarg(self) -> None:
     def test_encoding_kwarg_fixed_width_string(self) -> None:
         # CFEncodedInMemoryStore doesn't support explicit string encodings.
         pass
+
+
+class TestDecodeCFVariableWithArrayUnits:
+    def test_decode_cf_variable_with_array_units(self) -> None:
+        v = Variable(["t"], [1, 2, 3], {"units": np.array(["foobar"], dtype=object)})
+        v_decoded = conventions.decode_cf_variable("test2", v)
+        assert_identical(v, v_decoded)