tailscale/tailscale · error
TS_EXPERIMENTAL_DEST_DNS_NAME and TS_DEST_IP cannot both be
Error message
TS_EXPERIMENTAL_DEST_DNS_NAME and TS_DEST_IP cannot both be set
What it means
containerboot settings validation rejects setting both TS_EXPERIMENTAL_DEST_DNS_NAME and TS_DEST_IP. The proxy destination must be specified exactly one way (by IP or by DNS name); two conflicting targets would make forwarding behavior ambiguous, so startup aborts.
Source
Thrown at cmd/containerboot/settings.go:263
dir, file := path.Split(s.TailscaledConfigFilePath)
if _, err := os.Stat(dir); err != nil {
return fmt.Errorf("error validating whether directory with tailscaled config file %s exists: %w", dir, err)
}
if _, err := os.Stat(s.TailscaledConfigFilePath); err != nil {
return fmt.Errorf("error validating whether tailscaled config directory %q contains tailscaled config for current capability version %q: %w. If this is a Tailscale Kubernetes operator proxy, please ensure that the version of the operator is not older than the version of the proxy", dir, file, err)
}
if _, err := conffile.Load(s.TailscaledConfigFilePath); err != nil {
return fmt.Errorf("error validating tailscaled configfile contents: %w", err)
}
}
if s.ProxyTargetIP != "" && s.UserspaceMode {
return errors.New("TS_DEST_IP is not supported with TS_USERSPACE")
}
if s.ProxyTargetDNSName != "" && s.UserspaceMode {
return errors.New("TS_EXPERIMENTAL_DEST_DNS_NAME is not supported with TS_USERSPACE")
}
if s.ProxyTargetDNSName != "" && s.ProxyTargetIP != "" {
return errors.New("TS_EXPERIMENTAL_DEST_DNS_NAME and TS_DEST_IP cannot both be set")
}
if s.TailnetTargetIP != "" && s.UserspaceMode {
return errors.New("TS_TAILNET_TARGET_IP is not supported with TS_USERSPACE")
}
if s.TailnetTargetFQDN != "" && s.UserspaceMode {
return errors.New("TS_TAILNET_TARGET_FQDN is not supported with TS_USERSPACE")
}
if s.TailnetTargetFQDN != "" && s.TailnetTargetIP != "" {
return errors.New("Both TS_TAILNET_TARGET_IP and TS_TAILNET_FQDN cannot be set")
}
if s.TailscaledConfigFilePath != "" &&
(s.AcceptDNS != nil ||
s.AuthKey != "" ||
s.Routes != nil ||
s.ExtraArgs != "" ||
s.Hostname != "" ||
s.ClientID != "" ||
s.ClientSecret != "" ||View on GitHub (pinned to cfe32b8be6)
Solutions
- Decide on one destination mode: keep TS_DEST_IP for a stable IP, or TS_EXPERIMENTAL_DEST_DNS_NAME for a DNS-resolved backend, and delete the other
- If the DNS name and IP refer to the same backend, prefer the DNS name for stability across pod restarts
- Apply the corrected spec
Example fix
# before
env:
- name: TS_DEST_IP
value: "10.24.0.5"
- name: TS_EXPERIMENTAL_DEST_DNS_NAME
value: "backend.default.svc.cluster.local"
# after
env:
- name: TS_EXPERIMENTAL_DEST_DNS_NAME
value: "backend.default.svc.cluster.local"
# TS_DEST_IP removed Defensive patterns
Strategy: validation
Validate before calling
if [ -n "$TS_DEST_IP" ] && [ -n "$TS_EXPERIMENTAL_DEST_DNS_NAME" ]; then echo "invalid config: set only one of TS_DEST_IP or TS_EXPERIMENTAL_DEST_DNS_NAME" >&2 exit 1 fi
Prevention
- Model destination mode as a single Helm value (dest.ip vs dest.dnsName) that renders exactly one env var
- Clean up superseded variables when migrating between modes; empty string can still count as set in some templating stacks
- Diff the rendered Pod spec before applying
When it happens
Trigger: A proxy Deployment with both TS_DEST_IP and TS_EXPERIMENTAL_DEST_DNS_NAME set; migrating a manifest from IP-based to DNS-name-based destination without removing the old variable; Helm values that render both keys.
Common situations: Copy-paste during migration between destination modes; charts that template both env vars and enable both when values are populated.
Related errors
- TS_DEST_IP is not supported with TS_USERSPACE
- TS_EXPERIMENTAL_DEST_DNS_NAME is not supported with TS_USERS
- Both TS_TAILNET_TARGET_IP and TS_TAILNET_FQDN cannot be set
- EXPERIMENTAL_ALLOW_PROXYING_CLUSTER_TRAFFIC_VIA_INGRESS is s
- EXPERIMENTAL_ALLOW_PROXYING_CLUSTER_TRAFFIC_VIA_INGRESS is s
AI-assisted analysis of tailscale/tailscale@cfe32b8be6 (2026-08-15).
Data as JSON: /api/errors/d20810288f9dfcfd.
Report an issue: GitHub.