It's always DNS: Pi-hole, curl, FRITZ!Box
In my home network I'm running a Pi-hole. It runs as a Docker container on my Synology NAS. To distribute the Pi-hole as DNS server to the clients I configured the DHCP on my FRITZ!Box router. The NAS itself has a manually configured DNS server, set to the FRITZ!Box. In case the Docker container fails, the NAS and other services running on it still have access to a DNS server.
In the admin web-interface of the Pi-hole the used version numbers are usually displayed in the footer like this:

But recently I noticed that in my case it didn't show anything at all:

This started a small investigation what's actually happening here. The problem of missing version information seems to happen quite sometimes:
- https://github.com/pi-hole/pi-hole/issues/6288
- https://discourse.pi-hole.net/t/version-numbers-disappearing/76922
- https://discourse.pi-hole.net/t/versions-at-bottom-of-web-interface-is-missing-after-latest-v6-update/79039
The usual fix seems to be running the updatecheck of Pi-hole again and the issue usually resolves itself, but it didn't in my case.
Why are there no versions in the fronted?
The reason there are no version numbers shown in the footer is rooted in a JavaScript error. Inside the browser development console I got the following error:
Uncaught TypeError: can't access property 0, v2 is null
This error originates in the footer.js file, inside the versionCompare(v1, v2) function. Apparently it compares the version locally running and the latest available version, fetched from some external resource. In the case of v2 being null, this comparison v2[0] === "v" breaks the execution of the file, which in case leads to no version number displayed at all.
The intention here seems to be to only show the update link if an actual update is available, my suggestion would be to safeguard this, and in case the second version number is not available (for whatever reasons), display the unknown update situation to the user. But always make sure to show the locally running version. I opened an issue at their GitHub with this suggestion.
Where is the version information coming from?
The input for this JavaScript function to display the version numbers comes from the API call at /api/info/version (which is generated here). In this case a JSON structure containing all the version information is returned. It follows this structure for the different components of Pi-hole (Core, Web, FTL, Docker). Essentially it contains the local version as well as the latest "remote" version which is available.
The previously mentioned versionCompare function compares the local/remote version string and decides if the update notice should be shown. In my case some remote versions where null, which breaks the JavaScript execution.
Full JSON response
{
"version": {
"core": {
"local": {
"version": "v6.4",
"branch": "master",
"hash": "a393dd83"
},
"remote": {
"version": "v6.4",
"hash": "null"
}
},
"web": {
"local": {
"version": "v6.4.1",
"branch": "master",
"hash": "09e4e0ed"
},
"remote": {
"hash": "null",
"version": null
}
},
"ftl": {
"local": {
"hash": "f8883098",
"branch": "master",
"version": "v6.5",
"date": "2026-02-17 20:20:12 +0000"
},
"remote": {
"version": "v6.5",
"hash": "null"
}
},
"docker": {
"local": "2026.02.0",
"remote": null
}
},
"took": 0.0005...
}
The source of the JSON object returned from the API is a file containing the version information as a key-value structure, located at /etc/pihole/versions. It contains the local and remote version information in this style:
CORE_VERSION=v6.4
CORE_BRANCH=master
CORE_HASH=a393dd83
GITHUB_CORE_VERSION=v6.4
GITHUB_CORE_HASH=null
WEB_VERSION=v6.4.1
WEB_BRANCH=master
WEB_HASH=09e4e0ed
GITHUB_WEB_VERSION=
GITHUB_WEB_HASH=null
FTL_VERSION=v6.5
FTL_BRANCH=master
FTL_HASH=f8883098
GITHUB_FTL_VERSION=v6.5
GITHUB_FTL_HASH=null
DOCKER_VERSION=2026.02.0
GITHUB_DOCKER_VERSION=
The GITHUB_WEB_VERSION in my case has no value, which in turn gets converted into null in the JSON API response (filled in by JSON_ADD_NULL_IF_NOT_EXISTS).
How is the versions file filled?
The file at /etc/pihole/versions is created by the updatecheck.sh. It extracts the locally running version numbers and fetches the remote version number from the GitHub API, as well as the git revision for all the Pi-hole components.
This script seems to run at startup and periodically. To run it manually seems the usual recommendation to fix the missing version numbers. When I did run it manually it did not resolve the issue. Nevertheless, I noticed it running quite long. I narrowed it down to the curl calls. I modified the curl call in the file from curl -s "..." 2>/dev/null to curl -v "..." which resulted in more information being shown during the run of the script.
And then I saw the following error message for the second and following curl call to api.github.com:
Timeout while contacting DNS servers
But the first (and sometimes later) curl call were working!
If the curl call fails, an empty string is written into the the versions file, which than leads to the JavaScript error in the frontend.
Investigation the curl call
I could reproduce it also directly in a bash inside the container with the following sequence of commands, executed directly after each other.
curl "https://api.github.com" # works as expected
curl "https://api.github.com" # Leads to DNS server timeout
# Manually adding the name resolution also fixes it
curl --resolve api.github.com:443:140.82.121.5 https://api.github.com
# After waiting ca. 60s the original call works again
curl "https://api.github.com" # works
Documentation on --resolve. Also curl has some built-in caches.
I did run curl inside the container with a trace output:
# curl --trace - https://api.github.com
* Could not resolve host: api.github.com (Timeout while contacting DNS servers)
* Store negative name resolve for api.github.com:443
* shutting down connection #0
curl: (6) Could not resolve host: api.github.com (Timeout while contacting DNS servers)
Curl version ins the container (pi-hole 2026.02.0):
# curl --version
curl 8.17.0 (x86_64-alpine-linux-musl) libcurl/8.17.0 OpenSSL/3.5.5 zlib/1.3.1 br
otli/1.2.0 zstd/1.5.7 c-ares/1.34.6 libidn2/2.3.8 libpsl/0.21.5 nghttp2/1.68.0 ng
http3/1.13.1
Release-Date: 2025-11-05
Protocols: dict file ftp ftps gopher gophers http https imap imaps ipfs ipns mqtt
pop3 pop3s rtsp smb smbs smtp smtps telnet tftp ws wss
Features: alt-svc AsynchDNS brotli HSTS HTTP2 HTTP3 HTTPS-proxy IDN IPv6 Largefil
e libz NTLM PSL SSL threadsafe TLS-SRP UnixSockets zstd
But I didn't find any more information regarding this. Though the following details I collected:
- The curl version uses c-ares for DNS resolution (
c-ares/1.34.6) - The curl error message
Could not resolve hostseems to originate here - The c-ares error message
Timeout while contacting DNS serversoriginates here.
The "fix"
As mentioned in the beginning I am using the FRITZ!Box as DNS server on my NAS, and subsequently also in the containers running on it. For testing, I set the preferred DNS server on the NAS to something else (9.9.9.9). After restarting the container and executing the curl calls again it works instantaneous without any issues.
Setting the DNS server back to the FRITZ!Box results in the same error again.
Summary
- The
versionComparefunction insidefooter.jsdoesn't properly handlenullvalues, which leads to no version numbers displayed at all. - There is some mismatch between
"null"andnullduring the creation of the/etc/pihole/versionsfile (which cascades through the API response JSON object for/api/info/version) - The curl call in
updatecheck.shfails in some cases, apparently when used in short succession with a FRITZ!Box DNS server - Switching the DNS server of the host/container from the FRITZ!Box to some other DNS server resolves the issue with curl.
So I suppose the core issue is something in the FRITZ!Box? Or maybe how Docker is handled on a Synology NAS? I haven't investigated if it's possible to reproduce the behavior on another Docker host.