Skip to content

net: go DNS resolver fails to connect to local DNS server #67925

Closed
@danvolchek

Description

@danvolchek

Go version

go version go1.22.4 linux/arm64

Output of go env in your module/workspace:

GO111MODULE=''
GOARCH='arm64'
GOBIN=''
GOCACHE='/home/dan/.cache/go-build'
GOENV='/home/dan/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/dan/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/dan/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/dan/sdk/go1.22.4'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/dan/sdk/go1.22.4/pkg/tool/linux_arm64'
GOVCS=''
GOVERSION='go1.22.4'
GCCGO='gccgo'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build3858791460=/tmp/go-build -gno-record-gcc-switches'

What did you do?

Using a local nameserver (192.168.0.1, provided by my router) and the go DNS resolver, call net.LookupHost.

/etc/resolv.conf:

# Generated by NetworkManager
search Home
nameserver 192.168.0.1
nameserver 205.171.3.25
nameserver 2001:428::1
# NOTE: the libc resolver may not support more than 3 nameservers.
# The nameservers listed below may not be recognized.
nameserver 2001:428::2

main.go:

package main

import (
	"fmt"
	"net"
)

func main() {
	addrs, err := net.LookupHost("ghcr.io")
	fmt.Println(addrs, err)
}

What did you see happen?

LookupHost alternates between failing and then succeeding, over and over:

$ GODEBUG=netdns=2 go run main.go
go package net: confVal.netCgo = false  netGo = false
go package net: dynamic selection of DNS resolver
go package net: hostLookupOrder(ghcr.io) = files,dns
[] lookup ghcr.io on 192.168.0.1:53: no such host

$ GODEBUG=netdns=2 go run main.go
go package net: confVal.netCgo = false  netGo = false
go package net: dynamic selection of DNS resolver
go package net: hostLookupOrder(ghcr.io) = files,dns
[140.82.116.34] <nil>

<pattern repeats, failure then success then failure then success, etc>

The pattern is always like this - it never fails or succeeds twice in a row. It happens without setting GODEBUG as well.

What did you expect to see?

I expect LookupHost to always succeed.

More context:

  • Narrowing down the root cause:
    • DNS lookups from other tools on the machine (host, dig) never fail when connecting to 192.168.0.1 - so I don't think it's a connectivity issue.
    • Using the native/cgo resolver always succeeds - so I don't think it's an OS issue:
      $ GODEBUG=netdns=cgo+2 go run main.go
      go package net: confVal.netCgo = true  netGo = false
      go package net: using cgo DNS resolver
      go package net: hostLookupOrder(ghcr.io) = cgo
      [140.82.116.33] <nil>
      
    • Commenting out nameserver 192.168.0.1 in my /etc/resolv.conf makes the go DNS resolver always succeed - so I think it is specific to that server.
    • The device providing the local DNS server is CenturyLink Zyxel C3000Z in case it matters.
  • Reproducibility:
    • I've reproduced this in go1.19.8 linux/arm64 and go1.21.11 linux/arm64 (both on the same machine as above), and go1.22.4 linux/amd64 (on a different machine in my network).
    • I cannot reproduce this in go1.18.7 linux/arm (on an older machine, RPI 3B+ with Raspbian 10) - the go resolver always succeeds.
  • Impact:

Let me know if any more info is needed/what I can do to debug further. Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    FixPendingIssues that have a fix which has not yet been reviewed or submitted.NeedsFixThe path to resolution is known, but the work has not been done.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions