Troubleshooting: Volume attachment stuck due to CNI NetworkPolicies
| August 21, 2026
Longhorn v1.12.1 with networkPolicies.restrictInternalTraffic enabled and a CNI that enforces Kubernetes NetworkPolicy resources. Longhorn v1.12.1 creates these internal policies by default. If your CNI does not enforce NetworkPolicy, this workaround is not needed for traffic filtering.
Important: This article describes two independent traffic paths. Apply only the policy that matches your specific symptom and the networking features enabled in your cluster.
attaching, or an engine remains in starting.FailedAttachVolume or FailedMount event, or a detach operation does not finish.No route to host, or a failed connection to TCP port 3260.3260. The source may be reported with a CNI-specific identity such as world.ztunnel logs show a timeout for the HBONE tunnel to the Longhorn recovery backend on TCP port 15008.Note: The RWX symptom is specific to a mesh transport that tunnels the request through TCP port
15008. It is completely separate from the V1 iSCSI host-origin problem described above.
For the V1 data engine, the node’s kernel iSCSI initiator connects to the instance-manager iSCSI target. Because the initiator runs from the host network namespace, it is not a pod selected by the v1.12.1 instance-manager policy. As a result, a NetworkPolicy-enforcing CNI can deny the connection even though the Longhorn manager and instance-manager pods are healthy.
Warning: The source address evaluated by the CNI is implementation- and topology-specific. The CIDR
169.254.0.0/16used in the workaround below is merely a Cilium-specific example. It is not a portable Longhorn or Kubernetes default. Do not copy it unless the CNI verdict or flow logs for your cluster confirm it is the effective source range for your host iSCSI initiators. Pod, service, or node CIDRs are not substitutes for the exact source observed by the CNI.
The default recovery-backend policy permits the share-manager pod to reach the recovery-backend application on TCP port 9503. Istio Ambient first carries that pod-to-pod connection through an HBONE tunnel on TCP port 15008. The destination policy can deny the tunnel before the request reaches the recovery-backend application, causing share-manager recovery to fail even though TCP port 9503 is allowed.
This extra port is needed only when the deployed mesh actually uses TCP port 15008 for this path. Do not add it to a cluster without that specific mesh transport.
The CSI sidecar pods communicate with the longhorn-csi-plugin pods over the Unix socket at <kubelet-directory>/plugins/driver.longhorn.io/csi.sock. The CSI plugin then communicates with longhorn-manager over its normal network endpoint. Therefore, the workaround does not add CSI sidecar sources to a manager ingress policy; no direct CSI sidecar-to-manager ingress is required to fix this issue.
These are additive policies. They supplement the policies installed by Longhorn and do not replace or modify the Helm-managed policies.
Important: The YAML block below contains two distinct policies. If only one symptom applies to your cluster, remove the other YAML document before applying so you only grant the required access.
Save the following YAML, adjust the example CIDR if your CNI reports a different effective source, and apply it in the longhorn-system namespace (if Longhorn is installed in another namespace, update the manifests and commands accordingly).
# Use this CIDR only when CNI verdict or flow logs show that it is the
# effective source range for the node-hosted V1 iSCSI initiators.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: longhorn-instance-manager-v1-iscsi
namespace: longhorn-system
spec:
podSelector:
matchLabels:
longhorn.io/component: instance-manager
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 169.254.0.0/16
ports:
- protocol: TCP
port: 3260
---
# Apply this policy only when Istio Ambient or another applicable mesh
# transport uses TCP/15008 for share-manager to recovery-backend traffic.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: longhorn-recovery-backend-mesh
namespace: longhorn-system
spec:
podSelector:
matchLabels:
longhorn.io/recovery-backend: longhorn-recovery-backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
longhorn.io/component: share-manager
ports:
- protocol: TCP
port: 15008
Apply the saved file, for example:
kubectl apply -f longhorn-cni-networkpolicy-workaround.yaml
3260.A note on the example CIDR: 169.254.0.0/16 is an example for the reported Cilium setup (where a source such as 169.254.7.127 was observed). An ipBlock cannot express that the source must be the same node as the destination pod, so a broad range increases the set of clients that can reach TCP 3260. Keep the range narrow and review it if you ever change the CNI, routing, node addressing, or topology.
A note on the recovery-backend policy: This policy is narrower. It allows only the share-manager pod selector to reach the recovery-backend pod selector on TCP 15008. It does not open the application port 9503 to other sources, and it does not add access for CSI sidecars.
(Note: NetworkPolicy is additive, but a CNI can also enforce egress policy. If the source pods are isolated by egress policies, verify that their egress rules also permit the corresponding destination and port).
After applying the applicable policy or policies:
Confirm that each supplemental policy you applied exists only in longhorn-system:
kubectl get networkpolicy -n longhorn-system longhorn-instance-manager-v1-iscsi
kubectl get networkpolicy -n longhorn-system longhorn-recovery-backend-mesh
2. Re-check the CNI verdict or flow log. The V1 host-originated connection to the selected instance-manager pod on TCP `3260` should be allowed. For an Ambient deployment, the share-manager-to-recovery-backend tunnel on TCP `15008` should be allowed.
3. Retry the affected V1 volume attachment or detachment and confirm that the volume and engine leave the stuck state. Check the instance-manager logs for a successful iSCSI discovery or login and no new NetworkPolicy denial.
4. If the RWX symptom applies, retry recovery and confirm that the share-manager pod becomes ready. Check the share-manager and Ambient proxy logs for a successful recovery-backend connection.
If the CNI still denies the flow, **do not widen the policy blindly**. Re-check the destination pod labels, effective source address, source egress policy, mesh transport port, and whether the connection is using the expected node or pod path.
## Rollback
To remove only the supplemental policies you applied on v1.12.1, run the applicable command or commands:
kubectl delete networkpolicy -n longhorn-system –ignore-not-found
longhorn-instance-manager-v1-iscsi
kubectl delete networkpolicy -n longhorn-system –ignore-not-found
longhorn-recovery-backend-mesh
This does not remove Longhorn's Helm-managed policies. Removing the V1 policy can restore the original attachment failure, and removing the recovery policy can restore the Ambient RWX recovery failure. Delete each policy only after the corresponding traffic path is no longer needed.
## Upgrading to v1.12.2 and above
Longhorn v1.12.2 and later provide Helm values for these paths. Configure the V1 source CIDRs using the value that matches your CNI, and configure the recovery-backend port only for an applicable mesh transport:
```yaml
networkPolicies:
v1DataEngineInitiatorSourceCIDRs:
- 169.254.0.0/16
recoveryBackendAdditionalIngressPorts:
- 15008
The 169.254.0.0/16 entry remains only an example for the reported Cilium source range; derive the value from your own CNI observations.
In v1.12.2 and later, these values dictate the following behavior:
3260 rule without source filtering (meaning any source that can reach an instance-manager pod can connect to TCP 3260). Set explicit observed CIDRs when least-privilege filtering is required.9503 remains, but 15008 is not allowed). Only add 15008 when Istio Ambient or another deployed mesh transport uses that exact port for this recovery path.Migration steps: During the upgrade, add the values to the Helm release before removing the corresponding v1.12.1 supplemental policies. Render or inspect the resulting policies and verify the CNI flows. Once the Helm-managed policies contain the equivalent allowed paths, remove the v1.12.1 supplemental policies. If the upgrade is ever rolled back to v1.12.1, restore the supplemental policies as needed.
Recent articles
Copyright © 2019-2026 Longhorn a Series of LF Projects, LLC. Documentation Distributed under CC-BY-4.0.
The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation, please see our Trademark Usage page.
For website terms of use, trademark policy and other project policies please see lfprojects.org/policies.