diff --git a/docs/CNI/multus.md b/docs/CNI/multus.md
index 1f724848db334227aeb492f945446a297fc4e7f1..98d7554f80b37d0a3c894f9ca4dca8f495bad38f 100644
--- a/docs/CNI/multus.md
+++ b/docs/CNI/multus.md
@@ -17,6 +17,16 @@ kube_network_plugin_multus: true
 
 will install Multus and Calico and configure Multus to use Calico as the primary network plugin.
 
+### Cilium compatibility
+
+If you are using `cilium` as the primary CNI you'll have to set `cilium_cni_exclusive` to `false` to avoid cillium reverting multus config.
+
+```yml
+kube_network_plugin: cilium
+kube_network_plugin_multus: true
+cilium_cni_exclusive: false
+```
+
 ## Using Multus
 
 Once Multus is installed, you can create CNI configurations (as a CRD objects) for additional networks, in this case a macvlan CNI configuration is defined. You may replace the config field with any valid CNI configuration where the CNI binary is available on the nodes.
diff --git a/roles/kubernetes-apps/network_plugin/multus/tasks/main.yml b/roles/kubernetes-apps/network_plugin/multus/tasks/main.yml
index 54dd1ed6144411a67bd005b4b7428b68876a7239..d5dd01643f2f0738ee1c8abd7efe46d92b1e4c75 100644
--- a/roles/kubernetes-apps/network_plugin/multus/tasks/main.yml
+++ b/roles/kubernetes-apps/network_plugin/multus/tasks/main.yml
@@ -9,7 +9,7 @@
     state: "latest"
   delegate_to: "{{ groups['kube_control_plane'][0] }}"
   run_once: true
-  with_items: "{{ (multus_manifest_1.results | default([])) + (multus_nodes_list | map('extract', hostvars, 'multus_manifest_2.results') | default([]) | list) }}"
+  with_items: "{{ (multus_manifest_1.results | default([])) + (multus_nodes_list | map('extract', hostvars, 'multus_manifest_2') | map('default', []) | list | json_query('[].results')) }}"
   loop_control:
     label: "{{ item.item.name if item != None else 'skipped' }}"
   vars:
diff --git a/roles/kubespray-defaults/defaults/main/download.yml b/roles/kubespray-defaults/defaults/main/download.yml
index 687dc1d9296f87dccf4cca6884395dd2061829a1..067b673c97f41a7e7cb9851c54bdf07f2d3a07bf 100644
--- a/roles/kubespray-defaults/defaults/main/download.yml
+++ b/roles/kubespray-defaults/defaults/main/download.yml
@@ -122,7 +122,7 @@ cilium_enable_hubble: false
 kube_ovn_version: "v1.12.21"
 kube_ovn_dpdk_version: "19.11-{{ kube_ovn_version }}"
 kube_router_version: "v2.0.0"
-multus_version: "v3.8"
+multus_version: "v4.1.0"
 helm_version: "v3.15.4"
 nerdctl_version: "1.7.6"
 krew_version: "v0.4.4"
diff --git a/roles/network_plugin/multus/defaults/main.yml b/roles/network_plugin/multus/defaults/main.yml
index c6b7ecd9705a20e92d3a004d13d15a94d645eb36..2ddcc0f1a5c607c6226c7d2817da0a077d6c04f0 100644
--- a/roles/network_plugin/multus/defaults/main.yml
+++ b/roles/network_plugin/multus/defaults/main.yml
@@ -6,5 +6,4 @@ multus_cni_run_dir_host: "/run"
 multus_cni_conf_dir: "{{ ('/host', multus_cni_conf_dir_host) | join }}"
 multus_cni_bin_dir: "{{ ('/host', multus_cni_bin_dir_host) | join }}"
 multus_cni_run_dir: "{{ ('/host', multus_cni_run_dir_host) | join }}"
-multus_cni_version: "0.4.0"
 multus_kubeconfig_file_host: "{{ (multus_cni_conf_dir_host, '/multus.d/multus.kubeconfig') | join }}"
diff --git a/roles/network_plugin/multus/templates/multus-daemonset.yml.j2 b/roles/network_plugin/multus/templates/multus-daemonset.yml.j2
index 10c42c1751331db7389f6a9ddc50ee10772de6de..5f22d1bcb044de331f75b3ba584ae3df1ccc0914 100644
--- a/roles/network_plugin/multus/templates/multus-daemonset.yml.j2
+++ b/roles/network_plugin/multus/templates/multus-daemonset.yml.j2
@@ -24,6 +24,7 @@ spec:
     spec:
       hostNetwork: true
       dnsPolicy: ClusterFirstWithHostNet
+      priorityClassName: system-node-critical
       nodeSelector:
         kubernetes.io/arch: {{ image_arch }}
 {% if container_manager_types | length >= 2 %}
@@ -32,16 +33,34 @@ spec:
       tolerations:
       - operator: Exists
       serviceAccountName: multus
+      initContainers:
+      - name: install-multus-binary
+        image: {{ multus_image_repo }}:{{ multus_image_tag }}
+        command: ["/install_multus"]
+        args:
+        - "--type"
+        - "thin"
+        resources:
+          requests:
+            cpu: "10m"
+            memory: "15Mi"
+        securityContext:
+          privileged: true
+        terminationMessagePolicy: FallbackToLogsOnError
+        volumeMounts:
+        - name: cnibin
+          mountPath: {{ multus_cni_bin_dir }}
+          mountPropagation: Bidirectional
       containers:
       - name: kube-multus
         image: {{ multus_image_repo }}:{{ multus_image_tag }}
-        command: ["/entrypoint.sh"]
+        command: ["/thin_entrypoint"]
         args:
         - "--cni-conf-dir={{ multus_cni_conf_dir }}"
+        - "--multus-autoconfig-dir={{ multus_cni_conf_dir }}"
         - "--cni-bin-dir={{ multus_cni_bin_dir }}"
         - "--multus-conf-file={{ multus_conf_file }}"
         - "--multus-kubeconfig-file-host={{ multus_kubeconfig_file_host }}"
-        - "--cni-version={{ multus_cni_version }}"
         resources:
           requests:
             cpu: "100m"
@@ -55,6 +74,7 @@ spec:
           capabilities:
             add: ["SYS_ADMIN"]
 {% endif %}
+        terminationMessagePolicy: FallbackToLogsOnError
         volumeMounts:
 {% if container_manager == 'crio' %}
         - name: run