TLDR Solution: uv’s standalone Python looks for CA certificates at /etc/ssl/cert.pem, but NixOS uses /etc/ssl/certs/ca-bundle.crt. Add this to your configuration.nix:
# Fix uv python ssl.SSLCertVerificationError
environment.etc.certfile = {
source = "/etc/ssl/certs/ca-bundle.crt";
target = "ssl/cert.pem";
};
Problem Description
I’m encountering ssl.SSLCertVerificationError when using urllib.request with uv’s standalone Python installation on NixOS. Any HTTPS request fails with certificate verification errors.
Error Details
Traceback (most recent call last):
File "/home/u/.local/share/uv/python/cpython-3.13.6-linux-x86_64-gnu/lib/python3.13/urllib/request.py", line 1319, in do_open
h.request(req.get_method(), req.selector, req.data, headers,
~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
encode_chunked=req.has_header('Transfer-encoding'))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# ... stack trace abbreviated ...
ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1035)
Test Case
from urllib import request
with request.urlopen("https://github.com/langchain-ai/react-agent/archive/refs/heads/main.zip") as response:
assert response.status == 200
data = response.read()
print("resp len", len(data))
Root Cause Analysis
Using strace, I discovered that uv’s Python is looking for certificate files in the wrong locations:
strace -ff uv run python test.py
The relevant output shows:
[pid 164907] openat(AT_FDCWD, "/etc/ssl/cert.pem", O_RDONLY) = -1 ENOENT (No such file or directory)
[pid 164907] stat("/etc/ssl/certs/c2d044ad.0", 0x7ffda0bdae78) = -1 ENOENT (No such file or directory)
# ... multiple failed attempts to find certificate files ...
The issue: uv’s standalone Python expects system CA certificates at /etc/ssl/cert.pem, but NixOS stores them at /etc/ssl/certs/ca-bundle.crt.
Temporary Workaround
As a temporary fix, you can set the SSL_CERT_FILE environment variable:
export SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt
Permanent Solution
For a permanent fix on NixOS, add this to your configuration.nix:
# Fix uv python ssl.SSLCertVerificationError
environment.etc.certfile = {
source = "/etc/ssl/certs/ca-bundle.crt";
target = "ssl/cert.pem";
};
This creates a symbolic link from the expected location to the actual certificate bundle location.