v2rayA/v2rayA · error
dns upstream: invalid response: %w
Error message
dns upstream: invalid response: %w
What it means
exchangeDirect validates the DNS message received from a direct upstream with ValidateResponse and wraps any failure as "dns upstream: invalid response: %w". The reply arrived and parsed as DNS, but it is not an acceptable response — e.g. it is not a response to a query (QR bit unset), is malformed, or carries an unexpected opcode. This guards against spoofed or broken upstreams.
Source
Thrown at core/dns/upstream_stub.go:161
log.Printf("[dns upstream] TCP fallback error (attempt %d): %s %s → %s: %v", attempt+1,
dns.Type(uint16(query.QType)).String(), query.Name, upstream.Addr, err)
continue
}
}
break
}
if err != nil {
return nil, fmt.Errorf("dns upstream: exchange failed: %w", err)
}
if resp == nil {
return nil, nil
}
if err := ValidateResponse(resp); err != nil {
return nil, fmt.Errorf("dns upstream: invalid response: %w", err)
}
if err := ValidateQuestionMatch(resp, query.Name, query.QType); err != nil {
return nil, fmt.Errorf("dns upstream: question mismatch: %w", err)
}
var ttl uint32
if len(resp.Answer) > 0 {
ttl = resp.Answer[0].Header().Ttl
for _, rr := range resp.Answer[1:] {
if rr.Header().Ttl < ttl {
ttl = rr.Header().Ttl
}
}
}
dnsResp := &DnsResponse{
Query: *query,
RawMsg: resp,View on GitHub (pinned to 71e5442fc5)
Solutions
- Inspect resp.Rcode/flags via the log output or capture with tcpdump to see what the upstream actually returned.
- Switch to a trusted upstream (1.1.1.1, 8.8.8.8) or an encrypted one (DoH/DoT) to bypass port-53 interception.
- Complete captive-portal authentication or leave the intercepting network.
- Mark the failing upstream unhealthy in config and let a fallback upstream serve queries.
- Check whether a local firewall/NAT device is rewriting UDP/53 payloads.
Example fix
// before upstream addr: "192.168.1.1:53" // router hijacked by ISP, returns junk // after upstream addr: "1.1.1.1:53" // or enable DoH upstream to avoid interception
Defensive patterns
Strategy: retry
Validate before calling
// Sanity-check the upstream before use: a valid reply should parse and be a response
q := new(dns.Msg)
q.SetQuestion(dns.Fqdn("example.com."), dns.TypeA)
c := new(dns.Client)
r, _, err := c.Exchange(q, upstream.Addr)
if err != nil || r == nil || !r.Response || r.Rcode == dns.RcodeFormatError {
return fmt.Errorf("upstream %s returns invalid responses", upstream.Addr)
} Type guard
func isInvalidResponseErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "dns upstream: invalid response")
} Try / catch
resp, err := mgr.Exchange(upstream, query)
if err != nil {
var target *dns.Msg
if strings.Contains(err.Error(), "invalid response") {
log.Printf("upstream %s returned invalid reply, failing over: %v", upstream.Addr, err)
resp, err = mgr.Exchange(fallbackUpstream, query)
}
_ = target
if err != nil { return err }
} Prevention
- Avoid plain UDP/53 on untrusted networks (hotels, captive portals) — use DoH/DoT upstreams.
- Complete portal authentication before relying on DNS.
- Monitor upstream health and rotate away from resolvers that repeatedly fail validation.
- Pin well-known, DNSSEC-capable resolvers instead of router-provided DNS.
When it happens
Trigger: Calling UpstreamManager.Exchange on a direct upstream whose reply fails ValidateResponse: responses with QR=0, malformed flags/sections, or otherwise structurally invalid messages returned by the server or injected by a middlebox (captive portals, ISP hijackers).
Common situations: Captive portal or hotel/airport Wi-Fi intercepting port 53 and returning an HTML/redirect page or junk packet; a middlebox rewriting DNS payloads; a misconfigured upstream replying with queries instead of responses; spoofed answers on untrusted networks.
Related errors
- dns upstream: question mismatch: %w
- dns upstream: exchange failed: %w
- dns upstream: proxy question mismatch: %w
- dns pack: %w
- dns unpack: %w
AI-assisted analysis of v2rayA/v2rayA@71e5442fc5 (2026-09-05).
Data as JSON: /api/errors/5785eb90ad55f78e.
Report an issue: GitHub.