Python
requests library
self-signed certificate
SSL
HTTPS

How to get Python requests to trust a self signed SSL certificate?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Python requests verifies TLS certificates by default, so self signed certificates fail unless you explicitly trust the signing certificate. The correct fix is to provide a trusted CA bundle path, not disable verification globally. Secure trust configuration keeps development environments functional without weakening transport security.

Why Verification Fails

A self signed certificate is not signed by a public CA trusted by system bundles. requests uses certifi or system trust to validate server certificate chains, so unknown issuers trigger SSLError.

Correct Approach: Trust A Custom CA File

Pass the certificate or CA bundle path via verify.

python
1import requests
2
3url = "https://dev.internal.example"
4ca_path = "./certs/dev-ca.pem"
5
6resp = requests.get(url, verify=ca_path, timeout=10)
7print(resp.status_code)

This keeps verification enabled while extending trust with your certificate.

Session Wide Trust Configuration

For repeated calls, configure a session once.

python
1import requests
2
3session = requests.Session()
4session.verify = "./certs/dev-ca.pem"
5
6for path in ["/health", "/version"]:
7    r = session.get(f"https://dev.internal.example{path}", timeout=5)
8    print(path, r.status_code)

This avoids repeating verify argument everywhere.

Environment Variable Option

requests supports REQUESTS_CA_BUNDLE environment variable.

bash
export REQUESTS_CA_BUNDLE=./certs/dev-ca.pem
python app.py

Useful in CI and containerized environments where code should remain unchanged.

Temporary Bypass For Local Debug Only

You can disable verification with verify=False, but this is insecure and should be limited to short local debugging sessions.

python
1import requests
2import urllib3
3
4urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
5
6r = requests.get("https://dev.internal.example", verify=False, timeout=5)
7print(r.status_code)

Never use this in production or shared test environments with sensitive data.

Certificate Chain And Hostname Checks

Even with custom CA trust, requests can fail if:

  • Certificate hostname does not match URL.
  • Intermediate certificates are missing.
  • Certificate is expired or malformed.

Validate with OpenSSL tools and ensure full chain is presented by server.

Container And CI Setup

In containers, mount CA files and configure environment variable at runtime. Avoid embedding private certificates directly in source repository unless policy allows it.

Example Docker runtime argument:

bash
docker run -e REQUESTS_CA_BUNDLE=/certs/dev-ca.pem -v $(pwd)/certs:/certs app-image

This keeps trust artifacts external and rotatable.

Security Best Practices

  • Treat internal CA certs as configuration assets with change control.
  • Rotate certificates before expiry.
  • Use separate trust bundles per environment where needed.
  • Add smoke tests that validate TLS handshake in CI.

This prevents last minute outages due to certificate drift.

Developer Experience Improvements

Provide a bootstrap script that installs dev certificates and configures REQUESTS_CA_BUNDLE automatically for local environments. This avoids repeated manual setup and reduces support noise for new contributors.

Pair this with clear troubleshooting docs that explain common SSL errors and where certificate files should live on each platform. Consistent onboarding prevents insecure shortcuts like permanent verify=False usage.

Regular certificate expiry monitoring should be part of operational alerts so trust bundles are rotated before incidents occur.

For shared teams, publish a single canonical CA bundle path convention so scripts and services do not diverge by machine.

Common Pitfalls

  • Using verify=False as permanent fix.
  • Trusting server leaf certificate instead of CA chain when chain rotation is expected.
  • Forgetting hostname mismatch checks.
  • Hardcoding local file paths that break in CI or containers.
  • Committing private cert materials without governance.

Summary

  • Self signed cert errors are expected until trust is configured.
  • Use verify=/path/to/ca.pem or REQUESTS_CA_BUNDLE for secure trust setup.
  • Keep verification enabled in all non-debug environments.
  • Validate certificate chain and hostname if errors persist.
  • Manage trust files as environment configuration, not ad hoc code hacks.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.