How to Avoid Errors with Self-Signed Certificates When Basic Constraints are Not Critical in Python 3.13 with VERIFY_X509_STRICT

Python
2025-05-21 11:50 (2 days ago) ytyng

Note: This article discusses intentionally lowering the default security level. Please only proceed if you understand the risks and can tolerate them in your environment.

When attempting to make a request to an HTTP server using a self-signed SSL certificate with Python's Requests or httpx, you would use code similar to the following:

import httpx

ca_file_path = os.path.join(os.path.dirname(__file__), 'my-ca.crt')
content = httpx.get('https://my-internal-server.example.com/', verify=ca_file_path)
import requests

ca_file_path = os.path.join(os.path.dirname(__file__), 'my-ca.crt')

response = requests.get('https://my-internal-server.example.com/', verify=ca_file_path)

This works fine up through Python 3.12. However, with Python 3.13, if the X509v3 Basic Constraints of the CA certificate are not marked as Critical, you will encounter the following error:

httpx.ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: Basic Constraints of CA cert not marked critical (_ssl.c:1020)

To bypass this error in Python 3.13 without modifying the CA certificate, you can use the following:

import httpx
import ssl

ca_file_path = os.path.join(os.path.dirname(__file__), 'my-ca.crt')

context = ssl.create_default_context()
context.verify_flags &= ~ssl.VERIFY_X509_STRICT
context.load_verify_locations(ca_file_path)

response = httpx.get('https://my-internal-server.example.com/', verify=context)

This will allow you to bypass the issue.

Note: This is insecure.

Currently unrated
The author runs the application development company Cyberneura.
We look forward to discussing your development needs.

Archive

2025
2024
2023
2022
2021
2020
2019
2018
2017
2016
2015
2014
2013
2012
2011