Go version

go version go1.24.4 linux/amd64

Output of go env in your module/workspace:

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/<redacted>/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/<redacted>/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build3316459729=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='/home/<redacted>/coding/gocode/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/<redacted>/coding/gocode'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/<redacted>/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.24.4'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

package main

import (
    "fmt"
    "net"
)

func main() {
    _, err := net.LookupIP("dsfkdfsjkldfslkjfwe.xyz")
    nerr, _ := err.(*net.DNSError)
    fmt.Printf("name: %q, server: %q, err: %q\n", nerr.Name, nerr.Server, nerr.Err)
}

Output:

name: "dsfkdfsjkldfslkjfwe.xyz", server: "", err: "no such host"

What did you see happen?

nerr.Server is empty so the output string has no value for 'server'.

What did you expect to see?

nerr.Server should have the DNS server's address or hostname in there. The output string should look something like:

name: "dsfkdfsjkldfslkjfwe.xyz", server: "8.8.8.8:53", err: "no such host"

I capture the value of the Server field from the net.DNSError struct when a DNS error is returned in my program. In Go 1.21, the Server field would contain the DNS server that was queried. I was stuck on Go 1.21 for some time but when I leaped to Go 1.23.4 my tests detected that the Server field was not set anymore. I'm now using Go 1.24.4 and the value is still empty when I receive a DNSError.

Comment From: gabyhelp

Related Issues

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

Comment From: mateusz834

I think what happened is that on your system the cgo resolver is now used, instead of the go resolver. Try running your program with GODEBUG=netdns=go, the Server field is only populated when the Go resolver is being used, with other resolvers (cgo/system) we don't have any information about what server resolved that query. Personally i would never rely on the Server field, its purpose (i think) is just to generate a nice Error() message.

You mentioned that with go1.21 it worked, are you testing (1.21 vs 1.24) on the same machine? If so, please share the contents of /etc/resolv.conf and /etc/nsswitch.conf.

Comment From: arashpayan

You're absolutely right. Using the Go resolver produces the output I was expecting:

$ GODEBUG=netdns=go ./dnserr 
name: "dsfkdfsjkldfslkjfwe.xyz", server: "127.0.0.53:53", err: "no such host"

I'm only using the Server field to make it easier for the end user to understand DNS errors when they occur. It's not critical for functionality. I build the app with CGO_ENABLED=0 and the netgo tag so this must have only been a problem in my unit tests.

I'm using the same machine for Go 1.24 that I was using with Go 1.21.

/etc/resolv.conf:

# This is /run/systemd/resolve/stub-resolv.conf managed by man:systemd-resolved(8).
# Do not edit.
#
# This file might be symlinked as /etc/resolv.conf. If you're looking at
# /etc/resolv.conf and seeing this text, you have followed the symlink.
#
# This is a dynamic resolv.conf file for connecting local clients to the
# internal DNS stub resolver of systemd-resolved. This file lists all
# configured search domains.
#
# Run "resolvectl status" to see details about the uplink DNS servers
# currently in use.
#
# Third party programs should typically not access this file directly, but only
# through the symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a
# different way, replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.

nameserver 127.0.0.53
options edns0 trust-ad
search lan

And /etc/nsswitch.conf:

# /etc/nsswitch.conf
#
# Example configuration of GNU Name Service Switch functionality.
# If you have the `glibc-doc-reference' and `info' packages installed, try:
# `info libc "Name Service Switch"' for information about this file.

passwd:         files systemd sss
group:          files systemd sss
shadow:         files systemd sss
gshadow:        files systemd

hosts:          files mdns4_minimal [NOTFOUND=return] dns mymachines
networks:       files

protocols:      db files
services:       db files sss
ethers:         db files
rpc:            db files

netgroup:       nis sss
automount:  sss

Do you know if there's a way to force the tests to use the Go resolver?

Comment From: seankhliao

Closing as working as intended. see Resolver.PreferGo.

Unlike many projects, the Go project does not use GitHub Issues for general discussion or asking questions. GitHub Issues are used for tracking bugs and proposals only.

For questions please refer to https://github.com/golang/go/wiki/Questions