channel CLI: pure-Go resolver bypasses Tailscale MagicDNS on Linux #12
Labels
No labels
burndown-2026-06
coherence-core
consult
headless
interactive
P0
P1
P2
P3
P4
No milestone
No project
No assignees
1 participant
Due date
No due date set.
Dependencies
No dependencies set.
Reference
coilyco-flight-deck/otel-a2a-relay-cli#12
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Ported from closed coilyco-bridge/coily#101. Home moved to otel-a2a-relay-cli (coily channel removed in coily v2.51.0). Applies to the o2r-cli binary's HTTP client and any Go binary built the same way.
Symptom
channel read <id>fails from kai-server with:curl http://apifrom the same shell on the same host works fine and resolvesapito a tailnet IP (100.126.181.22at the time of writing).Cause
The binary is built with Go's default pure-Go resolver. The pure-Go resolver reads
/etc/resolv.confdirectly and sends queries to whatever nameserver is listed there. On Ubuntu kai-server that is127.0.0.53(systemd-resolved), which does not know Tailscale MagicDNS names. The pure-Go resolver does not consult/etc/nsswitch.conf, so it bypasses the Tailscale resolver entry that libc-based clients (curl,getent hosts,ssh, anything that callsgetaddrinfo) honor.Known Go-on-Linux footgun. Reference: golang/go#57757, Tailscale MagicDNS doc (systemd-resolved + Go interaction).
Fix options, ranked
-tags netcgo, or bakeGODEBUG=netdns=cgo+1. Routes Go's net package through libcgetaddrinfo, picking up nsswitch and the Tailscale entry. Lowest blast radius, no runtime config, fixes every verb that opens an HTTP connection. Cost: cgo enabled = need a C toolchain at build time.GODEBUG=netdns=cgo. Works, but every host has to be configured, so it drifts. Unblocks today (GODEBUG=netdns=cgo ... channel read <id>works, verified).tailscale.com/client/tailscale.LocalClient. More invasive, tailnet-only, breaks where tailscaled isn't local. Not the right call.Option 1 is the right move.
Acceptance
channel read <id>against a MagicDNS hostname succeeds from kai-server with no per-shell env tweak.Provenance
Surfaced in agentic-os-kai#292 while teaching an agent about the o2r agent-channel surface.
Closing. o2r is archived in the June 2026 surface reduction - an optional agent channel, unused autonomously. Handover doctrine moves to human-mediated.