{"record":{"id":"6e50c7a4f119d9b0","repo":"XTLS/Xray-core","slug":"failed-to-delete-interface-address-address","errorCode":null,"errorMessage":"failed to delete interface address {address}","messagePattern":"failed to delete interface address (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"proxy/tun/tun_linux.go","lineNumber":259,"sourceCode":"\t\tif err != nil {\n\t\t\t_ = t.unsetInterfaceAddresses()\n\t\t\treturn errors.New(\"invalid interface address \", address).Base(err)\n\t\t}\n\t\tif err := netlink.AddrAdd(t.tunLink, addr); err != nil {\n\t\t\t_ = t.unsetInterfaceAddresses()\n\t\t\treturn errors.New(\"failed to add interface address \", address).Base(err)\n\t\t}\n\t\tt.interfaceAddresses = append(t.interfaceAddresses, *addr)\n\t}\n\treturn nil\n}\n\nfunc (t *LinuxTun) unsetInterfaceAddresses() error {\n\tvar errs []error\n\tfor i := len(t.interfaceAddresses) - 1; i >= 0; i-- {\n\t\taddress := t.interfaceAddresses[i]\n\t\tif err := netlink.AddrDel(t.tunLink, &address); err != nil {\n\t\t\terrs = append(errs, errors.New(\"failed to delete interface address \", address.String()).Base(err))\n\t\t}\n\t}\n\tt.interfaceAddresses = nil\n\treturn errors.Combine(errs...)\n}\n\nfunc (t *LinuxTun) setSystemRoutes() error {\n\tif len(t.options.AutoSystemRoutingTable) == 0 {\n\t\treturn nil\n\t}\n\ttunIndex := t.tunLink.Attrs().Index\n\tfor _, cidr := range t.options.AutoSystemRoutingTable {\n\t\tprefix, err := netip.ParsePrefix(cidr)\n\t\tif err != nil {\n\t\t\treturn errors.New(\"invalid system route \", cidr).Base(err)\n\t\t}\n\t\tprefix = prefix.Masked()\n\t\t_, ipNet, _ := net.ParseCIDR(prefix.String())","sourceCodeStart":241,"sourceCodeEnd":277,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/proxy/tun/tun_linux.go#L241-L277","documentation":"During teardown (unsetInterfaceAddresses), Xray removes each address it previously added to the TUN link. If netlink.AddrDel fails for any address, this error is collected into a combined error. This is cleanup-path noise: it usually indicates the address was already removed or the link is already gone.","triggerScenarios":"Another process (network manager, `ip addr flush`, a prior crash cleanup) removed the address first; the TUN link destroyed before teardown; addresses modified externally while Xray ran.","commonSituations":"System shutdown racing Xray shutdown; manual `ip addr flush dev tun0` while the proxy runs; repeated start/stop cycles where the kernel already reclaimed the ephemeral device.","solutions":["Treat as non-fatal if addresses are verified absent afterwards (`ip addr show <tun>`)","Avoid externally manipulating TUN addresses while Xray owns the device","Stop Xray cleanly (SIGTERM) so its own teardown runs before any interface destruction"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// cleanup errors are collected; treat combined error as non-fatal\nif err := tun.Close(); err != nil {\n\tlog.Warnf(\"tun cleanup: %v (verify with `ip addr show`)\", err)\n}","preventionTips":["Stop xray gracefully so teardown sees a live link","Do not manually flush TUN addresses while xray runs","Log cleanup failures at warn level instead of aborting"],"tags":["tun","linux","netlink","cleanup","address"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}