diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md
index 9cbf1e412e..26c35cb6c8 100644
--- a/docs/CHANGELOG.md
+++ b/docs/CHANGELOG.md
@@ -17,6 +17,7 @@ The following tip changes can be tested by building VictoriaMetrics components f
 
 * BUGFIX: [VictoriaMetrics cluster](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html): fix potential panic in [multi-level cluster setup](https://docs.victoriametrics.com/Cluster-VictoriaMetrics.html#multi-level-cluster-setup) when top-level `vmselect` is configured with `-replicationFactor` bigger than 1. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2961).
 * BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): properly handle custom `endpoint` value in [ec2_sd_configs](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#ec2_sd_config). It was ignored since [v1.77.0](https://docs.victoriametrics.com/CHANGELOG.html#v1770) because of a bug in the implementation of [this feature request](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/1287).
+* BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): [dockerswarm_sd_configs](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#dockerswarm_sd_config): properly set `__meta_dockerswarm_container_label_*` labels instead of `__meta_dockerswarm_task_label_*` labels as Prometheus does. See [this issue](https://github.com/prometheus/prometheus/issues/9187).
 * BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): set `up` metric to `0` for partial scrapes in [stream parsing mode](https://docs.victoriametrics.com/vmagent.html#stream-parsing-mode). Previously the `up` metric was set to `1` when at least a single metric has been scraped before the error. This aligns the behaviour of `vmselect` with Prometheus.
 * BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): restart all the scrape jobs during [config reload](https://docs.victoriametrics.com/vmagent.html#configuration-update) after `global` section is changed inside `-promscrape.config`. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2884).
 * BUGFIX: [vmagent](https://docs.victoriametrics.com/vmagent.html): properly assume role with AWS ECS credentials. See [this issue](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/2875). Thanks to @transacid for [the fix](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/2876).
diff --git a/lib/promscrape/discovery/dockerswarm/tasks.go b/lib/promscrape/discovery/dockerswarm/tasks.go
index 922a7883e0..d589537635 100644
--- a/lib/promscrape/discovery/dockerswarm/tasks.go
+++ b/lib/promscrape/discovery/dockerswarm/tasks.go
@@ -15,7 +15,6 @@ type task struct {
 	ID                  string
 	ServiceID           string
 	NodeID              string
-	Labels              map[string]string
 	DesiredState        string
 	NetworksAttachments []struct {
 		Addresses []string
@@ -32,6 +31,11 @@ type task struct {
 			Ports []portConfig
 		}
 	}
+	Spec struct {
+		ContainerSpec struct {
+			Labels map[string]string
+		}
+	}
 	Slot int
 }
 
@@ -82,8 +86,8 @@ func addTasksLabels(tasks []task, nodesLabels, servicesLabels []map[string]strin
 			"__meta_dockerswarm_task_slot":          strconv.Itoa(task.Slot),
 			"__meta_dockerswarm_task_state":         task.Status.State,
 		}
-		for k, v := range task.Labels {
-			commonLabels["__meta_dockerswarm_task_label_"+discoveryutils.SanitizeLabelName(k)] = v
+		for k, v := range task.Spec.ContainerSpec.Labels {
+			commonLabels["__meta_dockerswarm_container_label_"+discoveryutils.SanitizeLabelName(k)] = v
 		}
 		var svcPorts []portConfig
 		for i, v := range services {
diff --git a/lib/promscrape/discovery/dockerswarm/tasks_test.go b/lib/promscrape/discovery/dockerswarm/tasks_test.go
index 4a1d1ed2f9..ed019c33ea 100644
--- a/lib/promscrape/discovery/dockerswarm/tasks_test.go
+++ b/lib/promscrape/discovery/dockerswarm/tasks_test.go
@@ -27,13 +27,13 @@ func Test_parseTasks(t *testing.T) {
     "Version": {
       "Index": 23
     },
-    "Labels": {
-	    "label1": "value1"
-    },
     "Spec": {
       "ContainerSpec": {
         "Image": "redis:3.0.6@sha256:6a692a76c2081888b589e26e6ec835743119fe453d67ecf03df7de5b73d69842",
-        "Init": false
+        "Init": false,
+        "Labels": {
+	    "label1": "value1"
+        }
       },
       "Resources": {
         "Limits": {},
@@ -70,8 +70,18 @@ func Test_parseTasks(t *testing.T) {
 					ID:        "t4rdm7j2y9yctbrksiwvsgpu5",
 					ServiceID: "t91nf284wzle1ya09lqvyjgnq",
 					NodeID:    "qauwmifceyvqs0sipvzu8oslu",
-					Labels: map[string]string{
-						"label1": "value1",
+					Spec: struct {
+						ContainerSpec struct {
+							Labels map[string]string
+						}
+					}{
+						ContainerSpec: struct {
+							Labels map[string]string
+						}{
+							Labels: map[string]string{
+								"label1": "value1",
+							},
+						},
 					},
 					DesiredState: "running",
 					Slot:         1,
@@ -97,7 +107,7 @@ func Test_parseTasks(t *testing.T) {
 				return
 			}
 			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("parseTasks() got = %v, want %v", got, tt.want)
+				t.Errorf("parseTasks() got\n%v\nwant\n%v", got, tt.want)
 			}
 		})
 	}
@@ -126,7 +136,6 @@ func Test_addTasksLabels(t *testing.T) {
 						ID:           "t4rdm7j2y9yctbrksiwvsgpu5",
 						ServiceID:    "t91nf284wzle1ya09lqvyjgnq",
 						NodeID:       "qauwmifceyvqs0sipvzu8oslu",
-						Labels:       map[string]string{},
 						DesiredState: "running",
 						Slot:         1,
 						Status: struct {
@@ -194,7 +203,6 @@ func Test_addTasksLabels(t *testing.T) {
 						ID:           "t4rdm7j2y9yctbrksiwvsgpu5",
 						ServiceID:    "tgsci5gd31aai3jyudv98pqxf",
 						NodeID:       "qauwmifceyvqs0sipvzu8oslu",
-						Labels:       map[string]string{},
 						DesiredState: "running",
 						Slot:         1,
 						NetworksAttachments: []struct {