tailscale/tailscale · error
flushing %s/%s: %w
Error message
flushing %s/%s: %w
What it means
DelBase's del helper: ClearChain (flush) on a table/chain errored with something other than not-exist (which returns nil as desired state). The flush of a Tailscale chain failed — typically permissions or transient ip(6)tables failure during teardown; %s/%s name the table and chain.
Source
Thrown at util/linuxfw/iptables_runner.go:409
if err := delChain(ipt, "nat", "ts-postrouting"); err != nil {
return err
}
}
return nil
}
// DelBase empties but does not remove custom Tailscale chains from
// netfilter via iptables.
func (i *iptablesRunner) DelBase() error {
del := func(ipt iptablesInterface, table, chain string) error {
if err := ipt.ClearChain(table, chain); err != nil {
if isNotExistError(err) {
// nonexistent chain. That's fine, since it's
// the desired state anyway.
return nil
}
return fmt.Errorf("flushing %s/%s: %w", table, chain, err)
}
return nil
}
for _, ipt := range i.getTables() {
if err := del(ipt, "filter", "ts-input"); err != nil {
return err
}
if err := del(ipt, "filter", "ts-forward"); err != nil {
return err
}
}
for _, ipt := range i.getNATTables() {
if err := del(ipt, "nat", "ts-postrouting"); err != nil {
return err
}
}
View on GitHub (pinned to 6e0912f979)
Solutions
- Retry DelBase — teardown runs while interfaces/rules may still be settling
- Verify privileges persist through shutdown (not a torn-down namespace)
- Tolerate leftover empty chains if a later cleanup pass runs: not-exist is already treated as success
Defensive patterns
Strategy: retry
When it happens
Trigger: Thrown at util/linuxfw/iptables_runner.go:409 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of tailscale/tailscale@6e0912f979 (2026-08-18).
Data as JSON: /api/errors/ce7d5b5044ac8485.
Report an issue: GitHub.