Deprecate non-keyword arguments in mask
diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst
index 645443c450146..f9a18330d1923 100644
--- a/doc/source/whatsnew/v1.3.0.rst
+++ b/doc/source/whatsnew/v1.3.0.rst
@@ -680,6 +680,7 @@ Deprecations
 - Deprecated behavior of :meth:`DatetimeIndex.union` with mixed timezones; in a future version both will be cast to UTC instead of object dtype (:issue:`39328`)
 - Deprecated using ``usecols`` with out of bounds indices for ``read_csv`` with ``engine="c"`` (:issue:`25623`)
 - Deprecated passing arguments as positional in :meth:`Index.set_names` and :meth:`MultiIndex.set_names` (except for ``names``) (:issue:`41485`)
+- Deprecated passing arguments (apart from ``cond`` and ``other``) as positional in :meth:`DataFrame.mask` and :meth:`Series.mask` (:issue:`41485`)
 - Deprecated passing arguments as positional in :meth:`DataFrame.clip` and :meth:`Series.clip` (other than ``"upper"`` and ``"lower"``) (:issue:`41485`)
 - Deprecated special treatment of lists with first element a Categorical in the :class:`DataFrame` constructor; pass as ``pd.DataFrame({col: categorical, ...})`` instead (:issue:`38845`)
 - Deprecated passing arguments as positional (except for ``"method"``) in :meth:`DataFrame.interpolate` and :meth:`Series.interpolate` (:issue:`41485`)
diff --git a/pandas/core/frame.py b/pandas/core/frame.py
index 1d45581fa5047..6e71cb49596c8 100644
--- a/pandas/core/frame.py
+++ b/pandas/core/frame.py
@@ -10720,6 +10720,21 @@ def where(
     ):
         return super().where(cond, other, inplace, axis, level, errors, try_cast)
 
+    @deprecate_nonkeyword_arguments(
+        version=None, allowed_args=["self", "cond", "other"]
+    )
+    def mask(
+        self,
+        cond,
+        other=np.nan,
+        inplace=False,
+        axis=None,
+        level=None,
+        errors="raise",
+        try_cast=lib.no_default,
+    ):
+        return super().mask(cond, other, inplace, axis, level, errors, try_cast)
+
 
 DataFrame._add_numeric_operations()
 
diff --git a/pandas/core/generic.py b/pandas/core/generic.py
index 3e6642d3b1a72..49dc71954fd8f 100644
--- a/pandas/core/generic.py
+++ b/pandas/core/generic.py
@@ -9062,7 +9062,7 @@ def mask(
                 "try_cast keyword is deprecated and will be removed in a "
                 "future version",
                 FutureWarning,
-                stacklevel=2,
+                stacklevel=4,
             )
 
         # see gh-21891
diff --git a/pandas/core/series.py b/pandas/core/series.py
index 871b7fb4f9f95..2f45a2adbdec7 100644
--- a/pandas/core/series.py
+++ b/pandas/core/series.py
@@ -5366,6 +5366,21 @@ def where(
     ):
         return super().where(cond, other, inplace, axis, level, errors, try_cast)
 
+    @deprecate_nonkeyword_arguments(
+        version=None, allowed_args=["self", "cond", "other"]
+    )
+    def mask(
+        self,
+        cond,
+        other=np.nan,
+        inplace=False,
+        axis=None,
+        level=None,
+        errors="raise",
+        try_cast=lib.no_default,
+    ):
+        return super().mask(cond, other, inplace, axis, level, errors, try_cast)
+
     # ----------------------------------------------------------------------
     # Add index
     _AXIS_ORDERS = ["index"]
diff --git a/pandas/tests/frame/indexing/test_mask.py b/pandas/tests/frame/indexing/test_mask.py
index 364475428e529..ac80426883dd5 100644
--- a/pandas/tests/frame/indexing/test_mask.py
+++ b/pandas/tests/frame/indexing/test_mask.py
@@ -90,6 +90,19 @@ def test_mask_dtype_bool_conversion(self):
         result = bools.mask(mask)
         tm.assert_frame_equal(result, expected)
 
+    def test_mask_pos_args_deprecation(self):
+        # https://github.com/pandas-dev/pandas/issues/41485
+        df = DataFrame({"a": range(5)})
+        expected = DataFrame({"a": [-1, 1, -1, 3, -1]})
+        cond = df % 2 == 0
+        msg = (
+            r"In a future version of pandas all arguments of DataFrame.mask except for "
+            r"the arguments 'cond' and 'other' will be keyword-only"
+        )
+        with tm.assert_produces_warning(FutureWarning, match=msg):
+            result = df.mask(cond, -1, False)
+        tm.assert_frame_equal(result, expected)
+
 
 def test_mask_try_cast_deprecated(frame_or_series):
 
diff --git a/pandas/tests/series/indexing/test_mask.py b/pandas/tests/series/indexing/test_mask.py
index a4dda3a5c0c5b..30a9d925ed7e5 100644
--- a/pandas/tests/series/indexing/test_mask.py
+++ b/pandas/tests/series/indexing/test_mask.py
@@ -86,3 +86,17 @@ def test_mask_stringdtype():
         dtype=StringDtype(),
     )
     tm.assert_series_equal(result, expected)
+
+
+def test_mask_pos_args_deprecation():
+    # https://github.com/pandas-dev/pandas/issues/41485
+    s = Series(range(5))
+    expected = Series([-1, 1, -1, 3, -1])
+    cond = s % 2 == 0
+    msg = (
+        r"In a future version of pandas all arguments of Series.mask except for "
+        r"the arguments 'cond' and 'other' will be keyword-only"
+    )
+    with tm.assert_produces_warning(FutureWarning, match=msg):
+        result = s.mask(cond, -1, False)
+    tm.assert_series_equal(result, expected)

- [x] xref #41485
- [x] tests added / passed
- [x] Ensure all linting tests pass, see [here](https://pandas.pydata.org/pandas-docs/dev/development/contributing.html#code-standards) for how to run them
- [x] whatsnew entry
