{"record":{"id":"c9901ae2db063082","repo":"netbirdio/netbird","slug":"failed-to-delete-link-s-w","errorCode":null,"errorMessage":"failed to delete link %s: %w","messagePattern":"failed to delete link (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/iface/iface_destroy_linux.go","lineNumber":18,"sourceCode":"//go:build linux && !android\n\npackage iface\n\nimport (\n\t\"fmt\"\n\n\t\"github.com/vishvananda/netlink\"\n)\n\nfunc (w *WGIface) Destroy() error {\n\tlink, err := netlink.LinkByName(w.Name())\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to get link by name %s: %w\", w.Name(), err)\n\t}\n\n\tif err := netlink.LinkDel(link); err != nil {\n\t\treturn fmt.Errorf(\"failed to delete link %s: %w\", w.Name(), err)\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":1,"sourceCodeEnd":23,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/client/iface/iface_destroy_linux.go#L1-L23","documentation":"The second half of Linux Destroy(): after the link is resolved, netlink.LinkDel asks the kernel to delete it and this error wraps the failure. Causes: insufficient privilege (EPERM without CAP_NET_ADMIN), the link being busy or referenced (EBUSY), a link type the kernel refuses to delete, or transient netlink socket errors.","triggerScenarios":"LinkDel returning EPERM/EBUSY/EINVAL: unprivileged daemon, interface still referenced by routes or firewall rules, or a halfway-removed interface during rapid up/down cycling.","commonSituations":"Containers with trimmed capabilities; external network daemons re-referencing the interface; repeated teardown/setup cycles racing kernel cleanup.","solutions":["Run `sudo ip link del <name>` to surface the exact errno","Clear routes and firewall references to the interface, then retry","Grant CAP_NET_ADMIN or run the daemon as root","If the kernel keeps refusing (EBUSY), reboot is the last resort"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := w.Destroy(); err != nil {\n    if _, lerr := net.InterfaceByName(w.Name()); lerr == nil {\n        // still present: transient refusal (EBUSY-class), retry once\n        err = w.Destroy()\n    }\n    return err\n}","preventionTips":["Tear down routes and firewall rules before deleting the link","Keep the required capabilities on the daemon","Retry once on EBUSY/EAGAIN-class refusals, then surface the errno"],"tags":["go","linux","netlink","interface","teardown"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}