diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst
index 2b437734a451a..a4aa3c28c3594 100644
--- a/doc/source/whatsnew/v3.0.0.rst
+++ b/doc/source/whatsnew/v3.0.0.rst
@@ -654,6 +654,7 @@ Datetimelike
 - Bug in :meth:`DatetimeIndex.is_year_start` and :meth:`DatetimeIndex.is_quarter_start` returning ``False`` on double-digit frequencies (:issue:`58523`)
 - Bug in :meth:`DatetimeIndex.union` and :meth:`DatetimeIndex.intersection` when ``unit`` was non-nanosecond (:issue:`59036`)
 - Bug in :meth:`Series.dt.microsecond` producing incorrect results for pyarrow backed :class:`Series`. (:issue:`59154`)
+- Bug in :meth:`_validate_inferred_freq` where DateTimeIndex incorrectly raised a ``ValueError`` when assigning a logically equivalent frequency (:issue:`61086`)
 - Bug in :meth:`to_datetime` not respecting dayfirst if an uncommon date string was passed. (:issue:`58859`)
 - Bug in :meth:`to_datetime` on float array with missing values throwing ``FloatingPointError`` (:issue:`58419`)
 - Bug in :meth:`to_datetime` on float32 df with year, month, day etc. columns leads to precision issues and incorrect result. (:issue:`60506`)
diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py
index eba738c926497..76dee09c6f813 100644
--- a/pandas/core/arrays/datetimelike.py
+++ b/pandas/core/arrays/datetimelike.py
@@ -2519,15 +2519,38 @@ def _validate_inferred_freq(
     -------
     freq : DateOffset or None
     """
+
     if inferred_freq is not None:
-        if freq is not None and freq != inferred_freq:
+        if freq is not None:
+            offset1, offset2 = to_offset(freq), to_offset(inferred_freq)
+            if type(offset1) == type(offset2):
+                if hasattr(offset1, "startingMonth") and hasattr(
+                    offset2, "startingMonth"
+                ):
+                    if (offset1.startingMonth - offset2.startingMonth) % 3 != 0:
+                        raise ValueError(
+                            f"Inferred frequency {inferred_freq} from passed "
+                            "values does not conform to passed frequency "
+                            f"{freq.freqstr}"
+                        )
+                    return freq
+                if (
+                    hasattr(offset1, "n")
+                    and hasattr(offset2, "n")
+                    and offset1.n != offset2.n
+                ):
+                    raise ValueError(
+                        f"Inferred frequency {inferred_freq} from passed "
+                        "values does not conform to passed frequency "
+                        f"{freq.freqstr}"
+                    )
+                return freq
             raise ValueError(
                 f"Inferred frequency {inferred_freq} from passed "
                 "values does not conform to passed frequency "
                 f"{freq.freqstr}"
             )
-        if freq is None:
-            freq = inferred_freq
+        freq = inferred_freq
 
     return freq
 
diff --git a/pandas/tests/indexes/datetimes/test_constructors.py b/pandas/tests/indexes/datetimes/test_constructors.py
index c418b2a18008b..c95e42ecd2258 100644
--- a/pandas/tests/indexes/datetimes/test_constructors.py
+++ b/pandas/tests/indexes/datetimes/test_constructors.py
@@ -1204,3 +1204,19 @@ def test_dti_constructor_object_dtype_dayfirst_yearfirst_with_tz(self):
         result2 = DatetimeIndex([val], tz="US/Pacific", yearfirst=True)
         expected2 = DatetimeIndex([yfirst]).as_unit("s")
         tm.assert_index_equal(result2, expected2)
+
+    def test_validate_inferred_freq_equivalence(self):
+        idx = date_range("2022-02-01", freq="QS-FEB", periods=4)
+
+        new_idx = DatetimeIndex(idx, freq="QS-MAY")
+        assert isinstance(new_idx, DatetimeIndex)
+
+        msg = (
+            "Inferred frequency .* from passed "
+            "values does not conform to passed frequency .*"
+        )
+        with pytest.raises(
+            ValueError,
+            match=msg,
+        ):
+            DatetimeIndex(idx, freq="QS-MAR")