Changelog

All notable changes to dns_exporter will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

v1.2.3 - 2026-06-01

Fixed

Fixed listening on IPv6 addresses - thanks @lewellien ! https://github.com/tykling/dns_exporter/pull/219/

v1.2.2 - 2026-03-09

Fixed

Fixed docker image builds on 32bit platforms, thanks @bb-Ricardo !

v1.2.1 - 2026-03-08

Changed

  • Change some unit tests to use donoevil.google.com instead of 404.example.com to trigger NXDOMAIN

Fixed

  • Pinned chardet to a version acceptable to requests (used in unit tests)

v1.2.0 - 2026-03-08

Changed

  • Change some unit tests to use different portnumbers to reduce risk of race conditions failing tests

  • Change Dockerfile to use Python 3.14 and refactor it a bit, thanks @dallemon!

  • Rename socket count metric from dnsexp_socket_count_total to dnsexp_sockets_total

v1.2.0-beta3 - 2025-11-26

Added

  • The socket cache now keeps a deque (list) of sockets for each destination making it possible to have multiple sockets open for busy servers. A new index label has been added to the socket metrics, and a new dnsexp_socket_count_total metric has been introduced to track the number of sockets.

Fixed

  • Truncated responses are no longer interpreted as successful. A new failure mode response_truncated has been introduced in the dnsexp_failure_reason metric to count truncated responses.

Changed

  • Some refactoring was done to ensure sockets are always closed when connection reuse is in use.

  • The udptcp protocol was refactored to be easier to understand and test.

  • Add timeout to all requests calls in tests.

  • Handle httpx.ReadTimeout in addition to httpx.ConnectTimeout exceptions in DoH code.

v1.2.0-beta2 - 2025-11-17

Added

  • A socket cache housekeeping background thread now takes care of deleting old or unused sockets. Three new command-line options were introduced for this, --connection-max-age-seconds to control when to delete a socket from the socket cache based on age (regardless of when it was last used), --connection-max-idle-seconds to control when to delete a socket from the socket cache based on when it was last used (regardless of age), and finally --connection-cleanup-interval-seconds to control the interval in seconds between cleanups.

Fixed

  • Log message at DEBUG level instead of WARNING when a DNS response is not received from a server

v1.2.0-beta1 - 2025-11-15

Fixed

  • Socket cache stats was not being updated for protocols doh/doh3/doq

  • Message about connection label being enabled or not was logged before logging was configured, so the message was not being shown.

  • Make the udptcp tests more reliable.

Changed

  • Refactor a bit to use self.query rather than pushing the query object around

v1.2.0-alpha2 - 2025-11-14

Added

  • Python 3.14 Tox runs.

  • pytest-rerunfailures test dependency added to retry failing tests

Fixed

v1.2.0-alpha1 - 2025-11-14

This release adds a new connection_reuse config option which (if set to true) will try to reuse the socket/connection when doing DNS lookups. This means that TCP/TLS/QUIC handshakes no longer need to be done every time (depending on how aggressively the DNS server harvests idle connections of course).

The new connection reuse feature is disabled by default, so unless you set connection_reuse to true in your config module or scrape jobs there should be no difference at all.

A new connection label can be used to determine if the connection was reused. The label will have the value new or reused. To avoid breaking existing dashboards the connection label is disabled by default and must be explicitly enabled by setting the environment variable DNSEXP_CONNECTION_LABEL to any value before starting dns_exporter.

Added

  • New connection_reuse configuration option (see above). Defaults to False.

  • New metrics for the socket cache (related to the connection reuse feature): dnsexp_socket_age_seconds, dnsexp_socket_transmit_bytes_total, dnsexp_socket_receive_bytes_total, dnsexp_socket_uses_total. All four metrics are gauges with the following labels: protocol, server, ip, verify, proxy

  • A Docker compose file is now included in the root of the project.

Fixed

  • Specifying valid_rcodes as a URL querystring parameter did not work, bug fixed and regression test added.

  • The fail_if_none_matches RR validator was broken for non-failing cases. Fixed in #174, thanks @bb-Ricardo!

  • The recursion_desired option did not actually disable RD when set to false. Fixed in #176, thanks @hp0724!

Changed

  • Dependencies updated

  • Linters updated

  • Unit tests for response validators moved to seperate tests/test_validators.py file.

v1.1.0 - 2025-02-24

No changes since v1.1.0-beta4

v1.1.0-beta4 - 2025-02-22

Changed

  • Better metadata for Docker image builds

v1.1.0-beta3 - 2025-02-18

Fixed

  • Docker image workflow was broken for some platforms

v1.1.0-beta2 - 2025-02-18

Changed

  • Update linters in .pre-commit-config.yaml and fix new linting issues

  • Convert CHANGELOG.md to CHANGELOG.rst and include in sphinx build/RTD

  • Rework Dockerfile, push images to both Dockerhub and Github

[v1.1.0-beta1] - 2025-01-26

Added

  • DNS-over-HTTP3 support: New protocol doh3 was added for doing DNS-over-QUIC wrapped in HTTP3, aka DNS-over-HTTP3.

  • Digestabot introduced to keep docker image digests up-to-date.

  • Proxy support for DoQ and DoH3. Issue #96.

Changed

  • Bump dnspython dependency minimum version to 2.7.0

  • Pass custom CA path as ssl.SSLContext for DoH2 requests to silence httpx DeprecationWarning

  • Refactor verify logic into new seperate methods get_tls_context() and get_tls_verify()

  • Verify that the configured verify_certificate_path exists in the filesystem, raise ConfigError if not.

  • Improve certificate related unit tests (parametrize and add more tests)

  • Move test_internal_metrics() test to seperate file, write metrics to temp file to ease debugging when the test breaks (which happens often).

  • Update and simplify Dockerfile

  • Move coverage.py, pytest and tox config to pyproject.toml.

Fixed

  • Docs url in package metadata (used for example in PyPi sidebar). Issue #11.

  • Make unit tests, mypy and linters happy after DoH3 addition.

  • Re-enable custom CA path support for DoQ. Only works with a CA file, not with a CA dir, for now (#132).

  • Socket reuse bug introduced with proxy support for QUIC based protocols.

[v1.0.0] - 2024-03-07

1.0.0 represents the first stable release of dns_exporter. Future changes (especially concerning metrics naming and labels) will follow semver rules regarding versioning. The goal is to never introduce dashboard breaking changes to metrics without bumping the major version.

The details about all the changes through the pre-releases are included below, but are probably only interesting if you have been using a pre-1.0 version. If you have existing dashboards with pre-1.0 data you will need to create new, seperate dashboards for 1.0 because the metrics have changed so much. You can use https://grafana.com/grafana/dashboards/20617-dns-exporter/ as a starting point for your own dashboards.

[v1.0.0-rc4] - 2024-03-06

Changed

  • Remove wrong buckets on response time Histogram, replace with default buckets

[v1.0.0-rc3] - 2024-03-06

Fixed

  • Catch httpx.ConnectTimeout from protocol doh as failure reason timeout

Changed

  • Add more labels to the dnsexp_scrape_failures_total metric so it has all the same labels as dnsexp_dns_query_time_seconds in addition to the reason label.

[v1.0.0-rc2] - 2024-03-06

Fixed

  • Always send Content-Length header for metrics responses

  • Do not overwrite no_nsid placeholder if a blank NSID is received from server (to avoid blank labels)

Changed

  • Add the monitor label in all examples, also the ones scraping internal metrics

[v1.0.0-rc1] - 2024-03-06

Changed

  • Minimum supported DNSPython version is now 2.5.0

  • Log at level warning when encountering an unknown failure

  • Remove failure reason connection_refused and report it as connection_error along with the rest of socket related errors.

  • Remove dnsexp_failures_total from per-scrape metrics. Failure reasons are now tracked only under /metrics.

  • Switch from http.server.HTTPServer to http.server.ThreadingHTTPServer

  • Add new failure reason invalid_response_statuscode for DoH failures.

  • The default for the collect_ttl_rr_value_length has been changed from 255 to 50 to reduce label cardinality.

  • Docs: Mention the importance of scraping internal metrics under /metrics

  • Docs: Mention adding a monitor label to identify the exporter in use, for setups where multiple instances of dns_exporter is running.

  • Update unit tests for all of the above

Fixed

  • Always send content-length header for static responses (#100, thanks @jcodybaker!)

[v1.0.0-beta6] - 2024-03-01

Added

  • Unit tests for proxy code

  • Unit tests for new code introduced to make ruff happy

  • New collect_ttl setting to control collection of per-RR TTL metrics. Default is true.

  • New verify_certificate bool setting to control validation of certificates on encrypted protocols. Default is true.

  • New verify_certificate_path str setting to override the system CA when validating certificates on encrypted protocols. Leave empty to use the default system CA. Default is an empty string.

Changed

  • Replace black, flake8, isort, pydocstyle with ruff

  • Some refactoring to reduce complexity and ease testing

  • Much linting

  • Move coverage.py config to .coveragerc to make showing measurement contexts in coverage html work

  • Proxy support for DoQ disabled, pending next dnspython release with https://github.com/rthalley/dnspython/pull/1060

  • Improve unit tests

  • Polish dockerhub action a bit (thanks @dallemon!)

  • Re-add custom histogram buckets for metric dnsexp_dns_responsetime_sedonds from 1 second doubling until 4194304 seconds (48 days).

  • Build docs in pre-commit to avoid breaking them

  • Include protocol, server, and proxy labels in the dnsexp_scrape_failures_total Counter metric.

Fixed

  • Fixed a bug which made fail_if_all_match_regexp validation succeed on the first matching RR (not considering further RRs).

[v1.0.0-beta5] - 2024-02-20

Changed

  • Updated some dev and test dependencies

  • Improve debug logging

  • Enable proxy support for all protocols except DoT

[v1.0.0-beta4] - 2024-02-19

Fixed

  • Update codecov GH action to silence warning in CI

  • Handle errors in unit test setup better

  • Wrote a real describe() method in the collector

  • Support dnspython 2.6.0 as well as earlier versions

  • Add ttl metrics for all rrs.

  • Improve logformat used during unit tests

Added

  • Basic proxy support for plain TCP DNS lookups, supported proxy types are SOCKS4, SOCKS5 and HTTP.

  • Introduced pytest-mock test dependency to help with testing proxy code

  • Three new failure modes: invalid_request_proxy, connection_error, connection_refused

Changed

  • Suppress warnings at runtime (to silence dependencies)

  • Fail with a nice message if the port is in use when starting the exporter

[v1.0.0-beta3] - 2024-02-15

Fixed

  • DockerHub workflow unbroken, take 2

[v1.0.0-beta2] - 2024-02-10

Fixed

  • DockerHub workflow unbroken

[v1.0.0-beta1] - 2024-02-09

Changed

  • Update CHANGELOG

  • Add more badges to README.md

[v1.0.0-alpha1] - 2024-02-08

Version 1.0.0 is a major refactor. It changes some metric names and has many internal changes. It also enables DoQ support. Most stuff should work as it did before 1.0.0 though.

The metrics exposed under /query (per-scrape metrics) are now:

  • dnsexp_dns_query_time_seconds (Gauge, unchanged)

  • dnsexp_dns_query_success (Gauge, unchanged)

  • dnsexp_dns_response_rr_ttl_seconds (Gauge, unchanged)

  • dnsexp_failures_total (Counter, renamed and changed from Enum)

The metrics exposed under /metrics (persistent exporter-internal metrics) are now:

  • dnsexp_build_version (Info, unchanged)

  • dnsexp_http_requests_total (Counter, unchanged)

  • dnsexp_http_responses_total (Counter, unchanged)

  • dnsexp_dns_queries_total (Counter, unchanged)

  • dnsexp_dns_responsetime_seconds (Histogram, renamed and changed from Counter)

  • dnsexp_scrape_failures_total (Counter, renamed and got a reason label)

Further changes are mostly technical details.

Added

  • RELEASE.md file describing how to do a release

  • build module to the dev extras in pyproject.toml

  • Python 3.12 support

  • Automatic DockerHub upload of containers when new releases are tagged

  • Automatic PyPi upload of packages when new releases are tagged

Changed

  • Delete the develop branch, main is the new default branch. Update RELEASE.md to reflect the change.

  • Update some development dependencies

  • Major refactor: move DNS lookup to a custom prometheus_client.registry.Collector class in collector.py

Fixed

[v0.3.0] - 2024-01-25

Changed

  • Split code into seperate modules

  • Rename dnsexp_dns_time_seconds to dnsexp_dns_query_time_seconds and change from Histogram to Gauge

  • Rename dnsexp_dns_success to dnsexp_dns_query_success

  • Rename dnsexp_dns_failure_reason to dnsexp_dns_query_failure_reason

  • Rename dnsexp_dns_record_ttl_seconds to dnsexp_dns_response_rr_ttl_seconds and change from Histogram to Gauge

Added

  • Command-line option to set listen IP, use -L or --listen-ip. Default is 127.0.0.1.

  • Unit tests

  • Github action to build a new dockerhub image when a new tag is pushed

  • Python3.12 is now tested in CI

  • Add a Dockerfile (thanks @dallemon)

[v0.2.0] - 2023-04-12

Changed

  • Split code into multiple modules

Added

  • Write unit tests

  • Write documentation

Fixed

  • Many, many bugs while writing unit tests

[v0.2.0-beta3] - 2023-01-09

Changed

  • Removed the config file requirement

  • Removed the requirement to supply a module in every scrape request

  • Updated README.md with more information

[v0.2.0-beta2] - 2023-01-08

This was the first public pre-release.

Added

  • CHANGELOG.md

  • release.sh