diff --git a/index-scheduler/src/error.rs b/index-scheduler/src/error.rs
index 880121f69..7ae96e0b7 100644
--- a/index-scheduler/src/error.rs
+++ b/index-scheduler/src/error.rs
@@ -15,7 +15,9 @@ pub enum Error {
     CorruptedTaskQueue,
     #[error("Task `{0}` not found")]
     TaskNotFound(TaskId),
-
+    // TODO: Lo: proper error message for this
+    #[error("Cannot delete all tasks")]
+    TaskDeletionWithEmptyQuery,
     // maybe the two next errors are going to move to the frontend
     #[error("`{0}` is not a status. Available status are")]
     InvalidStatus(String),
@@ -41,6 +43,7 @@ impl ErrorCode for Error {
             Error::IndexNotFound(_) => Code::IndexNotFound,
             Error::IndexAlreadyExists(_) => Code::IndexAlreadyExists,
             Error::TaskNotFound(_) => Code::TaskNotFound,
+            Error::TaskDeletionWithEmptyQuery => Code::TaskDeletionWithEmptyQuery,
             Error::InvalidStatus(_) => Code::BadRequest,
             Error::InvalidKind(_) => Code::BadRequest,
 
diff --git a/index-scheduler/src/lib.rs b/index-scheduler/src/lib.rs
index 07d896d7b..f18bd8683 100644
--- a/index-scheduler/src/lib.rs
+++ b/index-scheduler/src/lib.rs
@@ -56,6 +56,21 @@ impl Default for Query {
 }
 
 impl Query {
+    /// Return `true` iff every field of the query is set to `None`, such that the query
+    /// would match all tasks.
+    pub fn is_empty(&self) -> bool {
+        matches!(
+            self,
+            Query {
+                limit: None,
+                from: None,
+                status: None,
+                kind: None,
+                index_uid: None,
+                uid: None
+            }
+        )
+    }
     pub fn with_status(self, status: Status) -> Self {
         let mut status_vec = self.status.unwrap_or_default();
         status_vec.push(status);
diff --git a/meilisearch-http/src/routes/tasks.rs b/meilisearch-http/src/routes/tasks.rs
index 5b63ed7c5..f1248c8dd 100644
--- a/meilisearch-http/src/routes/tasks.rs
+++ b/meilisearch-http/src/routes/tasks.rs
@@ -209,6 +209,9 @@ async fn delete_tasks(
         index_uid,
         uid,
     };
+    if query.is_empty() {
+        return Err(index_scheduler::Error::TaskDeletionWithEmptyQuery.into());
+    }
 
     let filtered_query = filter_out_inaccessible_indexes_from_query(&index_scheduler, &query);
 
@@ -258,6 +261,7 @@ async fn get_tasks(
         Some(&req),
     );
 
+    // TODO: Lo: use `filter_out_inaccessible_indexes_from_query` here
     let mut filters = index_scheduler::Query::default();
 
     // Then we filter on potential indexes and make sure that the search filter
diff --git a/meilisearch-types/src/error.rs b/meilisearch-types/src/error.rs
index f6d2ad751..774883880 100644
--- a/meilisearch-types/src/error.rs
+++ b/meilisearch-types/src/error.rs
@@ -149,6 +149,7 @@ pub enum Code {
     NoSpaceLeftOnDevice,
     DumpNotFound,
     TaskNotFound,
+    TaskDeletionWithEmptyQuery,
     PayloadTooLarge,
     RetrieveDocument,
     SearchDocuments,
@@ -236,6 +237,10 @@ impl Code {
                 ErrCode::authentication("missing_authorization_header", StatusCode::UNAUTHORIZED)
             }
             TaskNotFound => ErrCode::invalid("task_not_found", StatusCode::NOT_FOUND),
+            // TODO: Lo: find the proper error name & message for this one
+            TaskDeletionWithEmptyQuery => {
+                ErrCode::invalid("task_deletion_with_empty_query", StatusCode::BAD_REQUEST)
+            }
             DumpNotFound => ErrCode::invalid("dump_not_found", StatusCode::NOT_FOUND),
             NoSpaceLeftOnDevice => {
                 ErrCode::internal("no_space_left_on_device", StatusCode::INTERNAL_SERVER_ERROR)