Fix ssl.SSLCertVerificationError with uv's Standalone Python

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.

1 Like

I’d rather think that we should configure or patch the package in nixpkgs to look on usual path (or consider hardcoding to ${cacert}/..., etc.)

1 Like