Sửa lỗi 'ssl.SSLCertVerificationError: certificate verify failed' trên macOS

beginner🍎 macOS2026-05-30| macOS (Monterey, Ventura, Sonoma, Sequoia), Python 3.6 - 3.13 (bản cài đặt chính thức từ python.org)

Error Message

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

Bế tắc khi bắt tay SSL (SSL Handshake)

Không gì làm gián đoạn một phiên lập trình hiệu quả bằng một lỗi bắt tay SSL bất ngờ. Mã nguồn của bạn có thể chạy hoàn hảo trên máy chủ Linux, và URL tải ngay lập tức trong Safari, nhưng script Python lại "ngỏm" ngay khi cố gắng lấy dữ liệu. Bạn bị bỏ lại với một thông báo lỗi traceback kết thúc bằng một dòng thông báo đầy cứng đầu.

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

Đây không phải là lỗi code hay lỗi máy chủ. Đó là một thiếu sót trong cấu hình. Các trình cài đặt Python chính thức từ Python.org dành cho macOS không sử dụng keychain của hệ thống cho các chứng chỉ gốc (root certificates). Thay vào đó, chúng tìm kiếm một bộ chứng chỉ riêng biệt thường không được kích hoạt mặc định. Về cơ bản, Python đang tìm kiếm danh sách các tổ chức phát hành chứng chỉ tin cậy (như DigiCert hay Let's Encrypt) nhưng không tìm thấy gì.

Chẩn đoán phạm vi lỗi

Hãy bắt đầu bằng việc kiểm tra xem vấn đề chỉ nằm ở Python hay ảnh hưởng đến toàn bộ hệ thống. Chạy một bài kiểm tra nhanh với curl trong Terminal:

curl -I https://google.com

Nếu bạn thấy phản hồi HTTP/2 200, hệ thống mạng macOS của bạn vẫn ổn. Vấn đề chỉ nằm ở module SSL nội bộ của Python. Kể từ phiên bản 3.6, Python trên macOS đi kèm với bản sao OpenSSL riêng, nhưng nó không tự động liên kết với kho lưu trữ tin cậy của hệ thống để tránh xung đột quyền hạn.

Giải pháp 1: Cách sửa chính thức "Một cú nhấp chuột"

Nếu bạn đã sử dụng trình cài đặt .pkg từ Python.org, một script tiện ích nhỏ đã có sẵn trên ổ cứng của bạn. Script chỉ nặng 1KB này sẽ cài đặt gói certifi—chứa một bộ khoảng hơn 150 chứng chỉ gốc—và tạo các liên kết tượng trưng (symbolic link) mà Python cần.

Mở Terminal và chạy lệnh này cho phiên bản cụ thể của bạn (ví dụ: 3.12 hoặc 3.13):

/Applications/Python\ 3.12/Install\ Certificates.command

Bạn không chắc mình đang dùng phiên bản nào? Sử dụng lệnh wildcard sau để tự động tìm và thực thi script:

open /Applications/Python\ 3.*/Install\ Certificates.command

Đợi khoảng 5 giây để quá trình hoàn tất. Nó sẽ cập nhật pip, cài đặt certifi và liên kết các đường dẫn chứng chỉ.

Giải pháp 2: Sử dụng biến môi trường (Workaround)

Các môi trường ảo (virtual environments) hoặc bản cài đặt qua Homebrew đôi khi bỏ qua hoàn toàn thư mục Applications. Trong trường hợp này, bạn có thể trỏ Python đến một bộ chứng chỉ hợp lệ một cách thủ công. Đầu tiên, hãy đảm bảo thư viện certifi đã có sẵn:

pip install --upgrade certifi

Tiếp theo, xác định đường dẫn chính xác của kho lưu trữ chứng chỉ:

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

Lệnh này thường trả về một đường dẫn như .../site-packages/certifi/cacert.pem. Để thay đổi này có hiệu lực vĩnh viễn, hãy thêm một biến môi trường vào tệp .zshrc của bạn (shell mặc định của macOS hiện đại):

echo "export SSL_CERT_FILE=$(python -c 'import certifi; print(certifi.where())')" >> ~/.zshrc
source ~/.zshrc

Xác minh kết quả

Bây giờ lỗi đã thực sự được sửa chưa? Chạy đoạn mã sau để xác minh rằng ngay cả các thư viện Python cơ bản cũng có thể thiết lập kết nối HTTPS:

python3 -c "import urllib.request; print(urllib.request.urlopen('https://google.com').getcode())"

Nếu kết quả trả về 200, mọi thứ đã hoạt động bình thường. Nếu bạn sử dụng thư viện requests, hãy thử thêm lệnh này:

python3 -c "import requests; print(requests.get('https://google.com').status_code)"

Kinh nghiệm cho tương lai

Việc phụ thuộc vào các thiết lập mặc định có thể gây rắc rối khi di chuyển giữa Windows, Linux và macOS.

Hãy ghi nhớ các quy tắc sau:

  • Thói quen sau khi cài đặt: Luôn chạy Install Certificates.command ngay sau khi cài đặt một phiên bản Python mới trên macOS.
  • Môi trường ảo: Mỗi môi trường có thể cần cài đặt certifi riêng nếu nó bị tách biệt khỏi các gói hệ thống.
  • Tránh bẫy "Verify=False": Đừng bao giờ bỏ qua lỗi này bằng cách sử dụng verify=False hoặc ssl._create_unverified_context() trong ứng dụng thực tế (production). Điều này sẽ vô hiệu hóa việc xác thực mã hóa, khiến dữ liệu của bạn dễ bị tấn công Man-In-The-Middle (MITM).

Related Error Notes