diff --git a/declearn/dataset/__init__.py b/declearn/dataset/__init__.py
index bc6504024ffe5291e44b8a8c507e5fd131548329..7436e1ceacea4b5235fbf4f2d97bce198f3d386c 100644
--- a/declearn/dataset/__init__.py
+++ b/declearn/dataset/__init__.py
@@ -30,7 +30,7 @@ API tools
 * [DataSpec][declearn.dataset.DataSpecs]:
     Dataclass to wrap a dataset's metadata.
 * [load_dataset_from_json][declearn.dataset.load_dataset_from_json]
-    Utility function to parse a JSON into a dataset object.
+    DEPRECATED Utility function to parse a JSON into a dataset object.
 
 Dataset subclasses
 ------------------
diff --git a/declearn/dataset/_base.py b/declearn/dataset/_base.py
index 02ac2d7496f83abbc82dac13e8aee523c940b760..c0f3bbe7fe9a6719b8823c2f417e647f0e3cea51 100644
--- a/declearn/dataset/_base.py
+++ b/declearn/dataset/_base.py
@@ -17,8 +17,9 @@
 
 """Dataset abstraction API."""
 
-from abc import ABCMeta, abstractmethod
-from dataclasses import dataclass
+import abc
+import dataclasses
+import warnings
 from typing import Any, Iterator, List, Optional, Set, Tuple, Union
 
 from declearn.typing import Batch
@@ -30,7 +31,7 @@ __all__ = [
 ]
 
 
-@dataclass
+@dataclasses.dataclass
 class DataSpecs:
     """Dataclass to wrap a dataset's metadata."""
 
@@ -43,7 +44,7 @@ class DataSpecs:
 
 
 @create_types_registry
-class Dataset(metaclass=ABCMeta):
+class Dataset(metaclass=abc.ABCMeta):
     """Abstract class defining an API to access training or testing data.
 
     A 'Dataset' is an interface towards data that exposes methods
@@ -57,13 +58,13 @@ class Dataset(metaclass=ABCMeta):
     straightforward to specify as part of FL algorithms.
     """
 
-    @abstractmethod
+    @abc.abstractmethod
     def get_data_specs(
         self,
     ) -> DataSpecs:
         """Return a DataSpecs object describing this dataset."""
 
-    @abstractmethod
+    @abc.abstractmethod
     def generate_batches(  # pylint: disable=too-many-arguments
         self,
         batch_size: int,
@@ -110,8 +111,8 @@ class Dataset(metaclass=ABCMeta):
         """
 
 
-def load_dataset_from_json(path: str) -> Dataset:
-    """Instantiate a dataset based on a JSON dump file.
+def load_dataset_from_json(path: str) -> Dataset:  # pragma: no cover
+    """DEPRECATED Instantiate a dataset based on a JSON dump file.
 
     Parameters
     ----------
@@ -125,7 +126,25 @@ def load_dataset_from_json(path: str) -> Dataset:
     -------
     dataset: Dataset
         Dataset (subclass) instance, reloaded from JSON.
+
+    Raises
+    ------
+    NotImplementedError
+        If the target `Dataset` does not implement a `load_from_json`
+        method (which was removed from the API in DecLearn 2.3.0).
     """
+    warnings.warn(
+        "'load_dataset_from_json' was deprecated in Declearn 2.4.0, after"
+        "'Dataset.load_from_json' was removed from the API in v2.3.0. It "
+        "may raise a 'NotImplementedError', and will be removed in DecLearn "
+        "2.6 and/or 3.0.",
+        category=DeprecationWarning,
+        stacklevel=2,
+    )
     dump = json_load(path)
     cls = access_registered(dump["name"], group="Dataset")
+    if not hasattr(cls, "load_from_json"):
+        raise NotImplementedError(
+            f"Dataset class '{cls}' does not implement 'load_from_json'."
+        )
     return cls.load_from_json(path)
diff --git a/declearn/main/_client.py b/declearn/main/_client.py
index aa387742886def2c3faccf05dbaf4bace1041a13..75491a6625151e40d9a0962e5670d9a6dc9ee1dd 100644
--- a/declearn/main/_client.py
+++ b/declearn/main/_client.py
@@ -66,12 +66,12 @@ class FederatedClient:
             In the latter three cases, the object's default logger will be set
             to that of this `FederatedClient`.
         train_data: Dataset or str
-            Dataset instance wrapping the training data, or path to
-            a JSON file from which it can be instantiated.
+            Dataset instance wrapping the training data.
+            (DEPRECATED) May be a path to a JSON dump file.
         valid_data: Dataset or str or None
-            Optional Dataset instance wrapping validation data, or
-            path to a JSON file from which it can be instantiated.
+            Optional Dataset instance wrapping validation data.
             If None, run evaluation rounds over `train_data`.
+            (DEPRECATED) May be a path to a JSON dump file.
         checkpoint: Checkpointer or dict or str or None, default=None
             Optional Checkpointer instance or instantiation dict to be
             used so as to save round-wise model, optimizer and metrics.
diff --git a/docs/release-notes/v2.4.0.md b/docs/release-notes/v2.4.0.md
index f75412991e6ddd9db5f6da73da44c5ed26f525da..e2af281ad0a1ababdd59f20aebae0c1b1d2b8416 100644
--- a/docs/release-notes/v2.4.0.md
+++ b/docs/release-notes/v2.4.0.md
@@ -278,3 +278,12 @@ Upcoming TensorFlow versions (v2.16 and onwards) introduce backward-breaking
 changes, which are probably due to the backend swap from Keras 2 to Keras 3.
 To keep safe, these versions are currently marked as unsupported, awaiting
 further investigation once version 2.16 is finalized.
+
+### Deprecate `declearn.dataset.load_from_json`
+
+As the `save_to_json` and `from_to_json` methods were removed from the
+`declearn.dataset.Dataset` API in DecLearn 2.3.0, there is no longer a
+guarantee that this function works (save with `InMemoryDataset`).
+
+As a consequence, this function should have been deprecated, and has now been
+documented as such planned for removal in DecLearn 2.6 and/or 3.0.