Skip to content

bdns: add metric for doh_transport_errors. - #9103

Merged
jsha merged 1 commit into
mainfrom
unbound-comms-error
Oct 19, 2026
Merged

jsha merged 1 commit into
mainfrom
unbound-comms-error

Conversation

@jsha

@jsha jsha commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

This will let us add clear alerting for when Unbound is having problems, as opposed to our subscribers' authoritative servers having problems.

The new counter, doh_transport_errors, counts things like connection refused, connection timeout, TLS errors, and so on. It does not count cases where we successfully received a DNS response but the RCODE was NXDOMAIN, REFUSED, SERVFAIL, etc. It also does not count cases where the HTTP response timed out, because those are typically "authoritative server was slow" cases, and not our fault.

Replace http.Client.Timeout (a whole-request timeout) with these three:

  • Dial timeout, hardcoded at 2s
  • TLS handshake timeout, hardcoded at 2s
  • ResponseHeaderTimeout, set to the configured dnsTimeout.

Add sentinel errors in ExchangeContext to indicate when an HTTP request timed out or was canceled. These replace the typecasting net.OpError / url.Error cases, and make them more precise: we only want to tell the user "query timed out" when it was their fault.

Change the retry logic significantly: previously we would retry only on net.Error where Timeout() was true. Now we retry on any error so long as the context is not done. Reasoning: the old code retried both on user-caused errors and some internal errors. Rearranging error returns made it necessary to tweak this and I decided to go with "retry everything up to maxTries."

Practical impact: a DNS request may now take at most 2s + 2s + maxTries * requestTimeout. Previously it would take at most maxTries * requestTimeout. In practice, dials are usually fast and we should not see much impact.

An LLM wrote the tests, which I reviewed, tweaked, and rewrote the comments for.

Fixes #9018

This will let us add clear alerting for when Unbound is having problems, as
opposed to our subscribers' authoritative servers having problems.

The new counter, `doh_transport_errors`, counts things like connection refused,
connection timeout, TLS errors, and so on. It does not count cases where we
successfully received a DNS response but the RCODE was NXDOMAIN, REFUSED,
SERVFAIL, etc. It also does not count cases where the HTTP _response_ timed out,
because those are typically "authoritative server was slow" cases, and not our
fault.

Replace http.Client.Timeout (a whole-request timeout) with these three:

 - Dial timeout, hardcoded at 2s
 - TLS handshake timeout, hardcoded at 2s
 - ResponseHeaderTimeout, set to the configured dnsTimeout.

Add sentinel errors in `ExchangeContext` to indicate when an HTTP
request timed out or was canceled. These replace the typecasting
net.OpError / url.Error cases, and make them more precise: we only
want to tell the user "query timed out" when it was their fault.

Change the retry logic significantly: previously we would retry
only on net.Error where Timeout() was true. Now we retry on any
error so long as the context is not done. Reasoning: the old code
retried both on user-caused errors and _some_ internal errors.
Rearranging error returns made it necessary to tweak this and I
decided to go with "retry everything up to maxTries."

Practical impact: a DNS request may now take at most 2s + 2s +
maxTries * requestTimeout. Previously it would take at most maxTries
* requestTimeout.  In practice, dials are usually fast and we should
not see much impact.
@ezekiel
ezekiel requested review from a team and beautifulentropy and removed request for a team and beautifulentropy October 19, 2026 16:30

@aarongable aarongable left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with nits

Comment thread bdns/dns.go
Comment thread bdns/dns.go
@jsha
jsha merged commit 6f1e392 into main Oct 19, 2026
19 checks passed
@jsha
jsha deleted the unbound-comms-error branch October 19, 2026 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Differentiate errors when the DNS resolver is unreachable versus a DNS error during validation

3 participants