{"record":{"id":"1a902586ad52ed11","repo":"XTLS/Xray-core","slug":"failed-to-add-interface-address-address","errorCode":null,"errorMessage":"failed to add interface address {address}","messagePattern":"failed to add interface address (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"proxy/tun/tun_linux.go","lineNumber":247,"sourceCode":"}\n\nfunc setinterface(network, address string, fd uintptr, iface *net.Interface) error {\n\treturn unix.BindToDevice(int(fd), iface.Name)\n}\n\nfunc (t *LinuxTun) setInterfaceAddresses() error {\n\tif len(t.options.Gateway) == 0 {\n\t\treturn nil\n\t}\n\tfor _, address := range t.options.Gateway {\n\t\taddr, err := netlink.ParseAddr(address)\n\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","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/proxy/tun/tun_linux.go#L229-L265","documentation":"After parsing a gateway address successfully, netlink.AddrAdd assigns it to the TUN link. If the kernel rejects the operation the already-added addresses are rolled back and this error wraps the netlink failure. Typical base causes: EEXIST (address already on the interface), ENODEV (link gone), or EPERM (missing CAP_NET_ADMIN).","triggerScenarios":"Running without root/CAP_NET_ADMIN; a TUN interface that already carries the same address (e.g. from a previous unclean shutdown or an external script); the link being deleted concurrently; duplicate entries in the gateway list.","commonSituations":"Xray started as non-root; a network-manager or previous Xray run left addresses on the device; duplicate gateway values in config; container without NET_ADMIN capability.","solutions":["Run Xray as root or grant CAP_NET_ADMIN (e.g. docker --cap-add=NET_ADMIN)","Check `ip addr show <tun>` and remove stale addresses, or dedupe the gateway list","Ensure the TUN device still exists at assignment time (no concurrent teardown)"],"exampleFix":"# before: stale address present\nip addr show tun0  # 172.19.0.1/30 already assigned\n\n# after\nip addr flush dev tun0\n# then start xray","handlingStrategy":"validation","validationCode":"// pre-flight: ensure privileges and no conflicting addresses\nif os.Geteuid() != 0 {\n\tlog.Fatal(\"tun mode requires root or CAP_NET_ADMIN\")\n}\n// dedupe gateways\nseen := map[string]bool{}\nfor _, gw := range cfg.Gateway {\n\tif seen[gw] { log.Fatalf(\"duplicate gateway %q\", gw) }\n\tseen[gw] = true\n}","typeGuard":null,"tryCatchPattern":"if err := tun.Start(); err != nil {\n\tif strings.Contains(err.Error(), \"failed to add interface address\") {\n\t\t// check `ip addr show <tun>`, flush stale addresses, restart\n\t}\n}","preventionTips":["Run xray with CAP_NET_ADMIN","Flush stale addresses on the TUN before start","Keep gateway entries unique"],"tags":["tun","linux","netlink","permissions","address"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}