Sửa lỗi ssl.SSLCertVerificationError: CERTIFICATE_VERIFY_FAILED trong Python

beginner🔒 SSL/TLS2026-04-16| Python 3.6+ trên macOS, Windows, Linux — thường gặp khi dùng requests, urllib3, pip hoặc bất kỳ kết nối HTTPS nào

Error Message

ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)
#python#ssl#requests#urllib#certificate#ca-bundle

TL;DR — Sửa Nhanh

Python không thể xác minh chứng chỉ SSL của máy chủ vì nó không tin tưởng Certificate Authority (CA) đã ký chứng chỉ đó. Chọn cách sửa phù hợp với tình huống của bạn:

  • macOS sau khi cài Python mới: chạy /Applications/Python 3.x/Install Certificates.command
  • Mạng công ty / chứng chỉ tự ký: trỏ Python đến CA bundle tùy chỉnh của bạn
  • pip bị lỗi: dùng pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org <package>
  • Giải pháp tạm thời (chỉ dùng khi dev): truyền verify=False vào requests — không bao giờ dùng trong môi trường production

Nguyên Nhân Gây Ra Lỗi

Mỗi lần Python thực hiện một cuộc gọi HTTPS đều có quá trình SSL handshake. Python kiểm tra chứng chỉ của máy chủ so với một bộ chứng chỉ CA đáng tin cậy — nếu quá trình kiểm tra đó thất bại, bạn sẽ gặp lỗi này.

Các nguyên nhân thường gặp:

  • Kho CA được tích hợp sẵn trong Python đã lỗi thời hoặc bị thiếu (điều này xảy ra với hầu hết mọi lần cài mới trên macOS từ python.org)
  • Mạng của bạn định tuyến lưu lượng qua proxy công ty — Zscaler và Netskope là những thủ phạm phổ biến nhất — vốn ký lại lưu lượng HTTPS bằng chứng chỉ của riêng chúng
  • Máy chủ sử dụng chứng chỉ tự ký hoặc do nội bộ cấp phát
  • Kho CA của hệ thống và kho CA của Python không đồng bộ
  • Gói certifi bị thiếu hoặc đã lỗi thời

Lỗi đầy đủ trông như thế này:

ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1129)

Cách Sửa 1 — macOS: Chạy Trình Cài Đặt Chứng Chỉ

Python tải về từ python.org trên macOS đi kèm với SSL bundle riêng — nhưng bundle đó không được liên kết với keychain của hệ thống và không tự động cập nhật. Hãy chạy trình cài đặt chứng chỉ đi kèm với Python:

# Thay 3.x bằng phiên bản thực tế của bạn (ví dụ: 3.11, 3.12)
/Applications/Python\ 3.x/Install\ Certificates.command

Hoặc chạy lệnh tương đương từ terminal:

pip install --upgrade certifi
/usr/local/bin/python3 -c "import ssl; print(ssl.get_default_verify_paths())"

Lệnh này cài gói certifi và liên kết SSL của Python với nó. Chỉ cần làm một lần, mất khoảng 10 giây.

Cách Sửa 2 — Cập Nhật hoặc Cài Đặt certifi

Trên bất kỳ hệ điều hành nào, gói certifi lỗi thời là nguyên nhân phổ biến. Hãy cập nhật nó trước:

pip install --upgrade certifi

Sau đó xác nhận Python thực sự đang dùng nó:

python -c "import certifi; print(certifi.where())"

Bạn sẽ thấy đường dẫn tương tự như /usr/local/lib/python3.11/site-packages/certifi/cacert.pem. Thư viện requests tự động dùng certifi — chỉ cần giữ cả hai gói được cập nhật cùng nhau.

Cách Sửa 3 — Mạng Công Ty / Chứng Chỉ CA Tùy Chỉnh

Proxy công ty là nguyên nhân khó phát hiện nhất. Các công cụ như Zscaler và Netskope chặn lưu lượng HTTPS của bạn và ký lại bằng chứng chỉ riêng của chúng. Python không tin tưởng chứng chỉ đó vì nó không có trong CA bundle mặc định.

Bước 1 — Lấy chứng chỉ root CA của công ty bạn. Hỏi bộ phận IT, hoặc xuất nó từ kho chứng chỉ của trình duyệt dưới dạng file .pem. Trong Chrome: Cài đặt → Quyền riêng tư và bảo mật → Bảo mật → Quản lý chứng chỉ → xuất root CA.

Bước 2 — Thêm vào CA bundle của certifi:

import certifi

# Tìm đường dẫn đến bundle của certifi
print(certifi.where())  # ví dụ: /usr/local/lib/python3.11/site-packages/certifi/cacert.pem

# Thêm chứng chỉ công ty vào bundle
cat /path/to/company-root-ca.pem >> $(python -c "import certifi; print(certifi.where())")

Bước 3 — Hoặc đặt biến môi trường (gọn hơn, và tồn tại sau khi nâng cấp certifi):

export REQUESTS_CA_BUNDLE=/path/to/company-root-ca.pem
export SSL_CERT_FILE=/path/to/company-root-ca.pem

Thêm các dòng đó vào ~/.bashrc hoặc ~/.zshrc để áp dụng vĩnh viễn.

Trong code dùng requests:

import requests

response = requests.get("https://internal.example.com", verify="/path/to/company-root-ca.pem")
print(response.status_code)

Cách Sửa 4 — Sửa pip Khi Không Thể Cài Gói

Đôi khi chính pip gặp lỗi chứng chỉ trước khi bạn có thể cài bất cứ thứ gì. Dùng flag --trusted-host để vượt qua:

pip install --trusted-host pypi.org --trusted-host files.pythonhosted.org requests

Gõ những flag đó mỗi lần sẽ rất mất thời gian. Hãy lưu chúng vào cấu hình pip:

# Linux/macOS: ~/.config/pip/pip.conf
# Windows: %APPDATA%\pip\pip.ini
[global]
trusted-host = pypi.org
               files.pythonhosted.org

Cách Sửa 5 — Tắt Xác Minh SSL (Chỉ Dùng Khi Dev/Debug)

Đây là giải pháp tạm thời, không phải cách sửa thực sự. Nó loại bỏ toàn bộ quá trình xác thực chứng chỉ — vì vậy chỉ dùng để debug nội bộ, không bao giờ dùng trong code production xử lý dữ liệu thực.

import requests
import urllib3

# Tắt cảnh báo InsecureRequestWarning
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

response = requests.get("https://example.com", verify=False)
print(response.status_code)

Với urllib (thư viện chuẩn):

import urllib.request
import ssl

ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE

with urllib.request.urlopen("https://example.com", context=ctx) as response:
    print(response.read())

Nghiêm túc mà nói — hãy dùng một trong các cách sửa ở trên thay thế. verify=False âm thầm khiến bạn dễ bị tấn công man-in-the-middle mà không có cảnh báo nào.

Cách Sửa 6 — Windows: Đồng Bộ Với Kho Chứng Chỉ Hệ Thống

Windows quản lý kho chứng chỉ riêng tách biệt khỏi Python. Bộ phận IT thường đẩy chứng chỉ CA của công ty vào đó qua Group Policy — nhưng Python mặc định không nhìn thấy chúng.

Cài pip-system-certs để kết nối hai bên:

pip install pip-system-certs

Sau đó, Python tin tưởng bất kỳ chứng chỉ nào mà máy Windows của bạn đã tin tưởng. Không cần xuất chứng chỉ thủ công.

Kiểm Tra Sau Khi Sửa

Sau khi áp dụng bất kỳ cách sửa nào, chạy kiểm tra nhanh:

python -c "import requests; r = requests.get('https://httpbin.org/get'); print(r.status_code)"

Kết quả mong đợi: 200

Để kiểm tra host cụ thể đang gặp lỗi:

python -c "
import ssl, socket
ctx = ssl.create_default_context()
with ctx.wrap_socket(socket.socket(), server_hostname='your-target-host.com') as s:
    s.connect(('your-target-host.com', 443))
    print('Certificate OK:', s.getpeercert()['subject'])
"

Kết nối thành công sẽ in ra subject của chứng chỉ máy chủ — dạng như (('commonName', 'your-target-host.com'),). Nếu bạn vẫn nhận được SSLCertVerificationError ở đây, nghĩa là cách sửa chưa có tác dụng.

Nên Dùng Cách Sửa Nào?

  • macOS + cài từ python.org → Cách sửa 1 (chạy Install Certificates.command)
  • certifi lỗi thời → Cách sửa 2 (pip install --upgrade certifi)
  • Proxy công ty / CA nội bộ → Cách sửa 3 (thêm CA công ty vào bundle hoặc đặt biến môi trường)
  • pip không thể kết nối đến PyPI → Cách sửa 4 (flag --trusted-host)
  • Windows + chứng chỉ công ty → Cách sửa 6 (pip-system-certs)
  • Chỉ debug nội bộ → Cách sửa 5 (verify=False)

Related Error Notes