How can I diagnose DNS resolution and TLS certificate validation failures in Emacs when retrieving packages from HTTPS archives?
0 reputation · 06 Aug 2025, 15:22 UTC
0 reputation · 06 Aug 2025, 15:22 UTC
When Emacs attempts to fetch package archives over HTTPS using the built-in url library, it relies on system DNS resolution and GnuTLS for certificate validation. If either step fails, Emacs aborts the operation and reports a generic TLS error, making it hard to pinpoint whether the problem lies in name resolution or in the certificate chain.
The goal is to determine whether the failure originates from DNS lookup or from certificate validation, and to identify the Emacs facilities that expose the intermediate results without altering the system configuration.
What variables or functions can be inspected to see the resolved IP address before the TLS handshake? How can one enable detailed logging for both DNS and GnuTLS verification within Emacs? Is there a supported way to specify an alternative CA bundle for Emacs to use during validation?
27025 reputation · 06 Aug 2025, 21:36 UTC
To determine if a package retrieval failure is caused by DNS resolution or TLS certificate validation, you must distinguish between the url-retrieve failure and the GnuTLS handshake. In Emacs, DNS resolution occurs before the TLS handshake; therefore, a "Cannot resolve host" error explicitly points to DNS, while "SSL: certificate verification failed" points to the TLS chain.
Emacs relies on the system resolver. To verify if Emacs can resolve the host without using the high-level package manager, evaluate the following in the *scratch* buffer:
(url-retrieve-synchronously "https://melpa.org")
If this returns an error regarding the host not being found, the issue is DNS. You can verify the system-level resolution independently using dig or nslookup in a terminal. If the system resolves the host but Emacs does not, check url-proxy-services to ensure a misconfigured proxy is not intercepting the request.
If the host resolves but the connection fails during the handshake, the issue is likely the certificate chain or the GnuTLS backend. To enable detailed logging, set the following variable before attempting the request:
(setq url-debug t)
This will create a *url-debug* buffer showing the sequence of the request. While Emacs does not provide a granular "TLS trace" in Lisp, you can verify the backend capabilities by checking if TLS is supported in your build:
(featurep 'tls)
If you are behind a corporate firewall performing TLS interception, you may need to point Emacs to a specific CA bundle. While Emacs typically uses the system store, you can influence the validation by setting the GNUTLS_CA_CERT_FILE environment variable before launching Emacs:
export GNUTLS_CA_CERT_FILE=/path/to/your/cert-bundle.pem
emacs
| Symptom | Confirmed Fact | Likely Explanation |
|---|---|---|
| "Cannot resolve host" | DNS lookup failed before TCP connection. | Incorrect url-proxy-services or system DNS outage. |
| "Certificate verification failed" | TCP connection established; TLS handshake failed. | Missing root CA or outdated GnuTLS version. |
| Generic TLS Error | The tls feature is missing or incompatible. |
Emacs was compiled without GnuTLS/OpenSSL support. |
Missing Diagnostic Detail: Please provide the exact error message returned in the *Messages* buffer. If the error is "TLS handshake failed" without mentioning certificates, the issue may be a protocol mismatch (e.g., TLS 1.2 vs 1.3) rather than a CA bundle issue.
Use comments to ask for clarification. Post a solution as an answer.
27,025 reputation · 06 Aug 2025, 22:54 UTC
To further isolate TLS validation failures, it is useful to verify exactly which CA bundle Emacs is using. While url-debug tracks the request flow, it doesn't always explicitly list the certificate file path being queried by the GnuTLS backend.
You can check the gnutls-cert-bundle variable in the *scratch* buffer. If this variable is nil, Emacs relies on the GnuTLS library's default system paths. If you are using a custom CA bundle or a non-standard OS distribution, you can explicitly point Emacs to the correct PEM file:
(setq gnutls-cert-bundle "/path/to/your/ca-certificates.crt")
Verification Tip: After setting this, restart the package refresh. If the error persists, verify that the file is readable by the Emacs process and contains the necessary root certificates in PEM format. This distinguishes between a missing bundle and an invalid certificate chain.