{"record":{"id":"519390e21cca8cc2","repo":"tailscale/tailscale","slug":"error-checking-if-chain-s-exists-w","errorCode":null,"errorMessage":"error checking if chain %s exists: %w","messagePattern":"error checking if chain (.+?) exists: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/linuxfw/nftables_for_svcs.go","lineNumber":77,"sourceCode":"// It finds the matching rule using metadata attached to the rule.\n// The caller is expected to call DeleteSvc if the whole service (the chain)\n// needs to be deleted, so we don't deal with the case where this is the only\n// rule in the chain here.\nfunc (n *nftablesRunner) DeletePortMapRuleForSvc(svc, tun string, targetIP netip.Addr, pm PortMap) error {\n\ttable, err := n.getNFTByAddr(targetIP)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error setting up nftables for IP family of %s: %w\", targetIP, err)\n\t}\n\tt, err := getTableIfExists(n.conn, table.Proto, \"nat\")\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error checking if nat table exists: %w\", err)\n\t}\n\tif t == nil {\n\t\treturn nil\n\t}\n\tch, err := getChainFromTable(n.conn, t, svc)\n\tif err != nil && !errors.Is(err, errorChainNotFound{t.Name, svc}) {\n\t\treturn fmt.Errorf(\"error checking if chain %s exists: %w\", svc, err)\n\t}\n\tif errors.Is(err, errorChainNotFound{t.Name, svc}) {\n\t\treturn nil // service chain does not exist, so neither does the portmapping rule\n\t}\n\tmeta := svcPortMapRuleMeta(svc, targetIP, pm)\n\trule, err := n.findRuleByMetadata(t, ch, meta)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error checking if rule exists: %w\", err)\n\t}\n\tif rule == nil {\n\t\treturn nil\n\t}\n\tif err := n.conn.DelRule(rule); err != nil {\n\t\treturn fmt.Errorf(\"error deleting rule: %w\", err)\n\t}\n\treturn n.conn.Flush()\n}\n","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/tailscale/tailscale/blob/6e0912f97994f927632b34ae9e63b53d6516a6ac/util/linuxfw/nftables_for_svcs.go#L59-L95","documentation":"DeletePortMapRuleForSvc failed to fetch the per-service chain from the nat table; getChainFromTable returned an error other than the expected errorChainNotFound sentinel. This is a genuine lookup failure (netlink error), not a missing chain — a missing chain is handled by returning nil.","triggerScenarios":"Thrown at util/linuxfw/nftables_for_svcs.go:77 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Retry the chain lookup after a short delay.","Inspect the wrapped error for the underlying netlink cause.","Verify table/chain state with 'nft list table ip nat'."],"exampleFix":null,"handlingStrategy":"type-guard","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"6e0912f97994f927632b34ae9e63b53d6516a6ac","analyzedAt":"2026-08-18T08:17:25.280Z","contentChangedAt":"2026-08-18T08:17:25.280Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}