# DNS-over-HTTPS (DoH)

Google Public DNS provides two distinct DoH APIs at these endpoints:

- https://dns.google/dns-query -- [RFC 8484](https://tools.ietf.org/html/rfc8484) (GET and POST)
- https://dns.google/resolve? -- [JSON API](https://developers.google.com/speed/public-dns/docs/doh/json) (GET)

> [!NOTE]
> **Note:** There is also a human-friendly web interface at <https://dns.google/>. This web app displays JSON results in a browser but does not implement an API; do not confuse its https://dns.google/query? URLs with the two API URLs.

The [Secure Transports Overview](https://developers.google.com/speed/public-dns/docs/secure-transports#doh)
page has `curl` command line examples for using both APIs as well as details of
TLS and other features common to both DNS over TLS (DoT) and DoH.

DoH is also supported for the IPv6-only
[Google Public DNS64 service](https://developers.google.com/speed/public-dns/docs/dns64#secure).

Google Public DNS does not support insecure `http:` URLs for API calls.

## HTTP methods

GET
:   Using the GET method can reduce latency, as it is cached more effectively.
    RFC 8484 GET requests must have a `?dns=` query parameter with a
    Base64Url encoded DNS message.
    The GET method is the only method supported for the JSON API.

POST
:   The POST method is only supported for the RFC 8484 API and uses a binary DNS
    message with Content-Type application/dns-message in the request body and in
    the DoH HTTP response.

HEAD
:   *HEAD is not currently supported, and returns a 400 Bad Request error*.

Other methods return 501 Not Implemented errors.

## HTTP status codes

Google Public DNS DoH returns the following HTTP status codes:

### Success

200 OK
:   HTTP parsing and communication with DNS resolver was successful, and the
    response body content is a DNS response in either binary or JSON encoding,
    depending on the query endpoint, Accept header and GET parameters.

> [!NOTE]
> **Note:** An HTTP success may still be a DNS failure. Check the DNS response code (JSON "Status" field) for the DNS errors SERVFAIL, FORMERR, REFUSED, and NOTIMP.

### Redirections

301 Moved Permanently
:   Clients should retry at the URL provided in the `Location:` header. If the
    original query was a POST request, clients should only retry with GET if the
    new URL specifies a `dns` GET parameter argument; otherwise clients should
    retry with POST.

Other codes such as 302 Found, 307 Temporary Redirect or 308 Permanent Redirect
may be used in the future, and DoH clients should handle all four codes.

Responses with the permanent 301 and 308 codes should be cached indefinitely,
and if practical, users may be prompted to update their original configuration
using the new URL.

POST requests that get 307 or 308 responses should always be retried with POST.

### Errors

Error responses will have an explanation of the HTTP status in the body,
using either HTML or plain text.

400 Bad Request
:   Problems parsing the GET parameters, or an invalid DNS request message.
    For bad GET parameters, the HTTP body should explain the error. Most invalid
    DNS messages get a 200 OK with a FORMERR; the HTTP error is returned for
    garbled messages with no Question section, a QR flag indicating a reply, or
    other nonsensical flag combinations with binary DNS parse errors.

413 Payload Too Large
:   An RFC 8484 POST request body exceeded the 512 byte maximum message size.

414 URI Too Long
:   The GET query header was too large or the `dns` parameter had a Base64Url
    encoded DNS message exceeding the 512 byte maximum message size.

415 Unsupported Media Type
:   The POST body did not have an `application/dns-message` Content-Type header.

429 Too Many Requests
:   The client has sent too many requests in a given amount of time. Clients
    should stop sending requests until the time specified in the Retry-After
    header (a relative time in seconds).

500 Internal Server Error
:   Google Public DNS internal DoH errors.

501 Not Implemented
:   Only GET and POST methods are implemented, other methods get this error.

502 Bad Gateway
:   The DoH service could not contact Google Public DNS resolvers.

In the case of a 502 response, although retrying on an alternate Google Public
DNS address might help, a more effective fallback response would be to try
another DoH service, or to switch to traditional UDP or TCP DNS at 8.8.8.8.

## Benefits of DoH

Using HTTPS, not just TLS encryption, has some practical benefits:

- Widely available and well-supported HTTPS APIs simplify implementation for both Google Public DNS itself and potential clients.
- An HTTPS service provides web apps with access to all DNS record types, avoiding the limitations of existing browser and OS DNS APIs, which generally support only host-to-address lookups.
- Clients that implement QUIC UDP-based HTTPS support can avoid problems like head-of-line blocking that can occur when using TCP transport.

## Privacy Best Practices for DoH

Developers of DoH applications should consider the privacy best practices
outlined in [RFC 8484](https://tools.ietf.org/html/rfc8484#section-8) and
expanded below:

- Limit use of HTTP Headers

  HTTP headers reveal information about the client's DoH implementation and
  can be used to deanonymize clients. Headers like Cookie, User-Agent, and
  Accept-Language are the worst offenders, but even the set of headers sent
  can be revealing. To minimize this risk, send only the HTTP headers required
  for DoH: Host, Content-Type (for POST), and if necessary, Accept.
  User-Agent should be included in any development or testing versions.
- Use EDNS padding options

  Follow the guidance in [RFC 8467](https://tools.ietf.org/html/rfc8467) for
  use of EDNS padding options to pad DoH queries to a few common lengths to
  protect against traffic analysis. Use of HTTP/2 padding is also possible but
  unlike EDNS padding, will not elicit padding on responses from DoH servers.
- Use RFC 8484 POST only for privacy sensitive applications or browser modes

  Using POST for DoH queries reduces the cacheability of responses and can
  increase DNS latency, so it is not generally recommended. However, reducing
  caching is probably desirable for privacy sensitive applications, and might
  protect against timing attacks from web apps trying to determine what
  domains the user has visited lately.

## Issues

To report a bug or request a new feature, please open an [issue for DoH](https://issuetracker.google.com/issues/new?component=191657&template=1189745).