OpenAI Python HTTPX2: What Actually Breaks
The OpenAI Python HTTPX2 switch shipped in v3.0.0 and removed httpx and certifi from your install. Here are the two errors it causes, and how to get out.
Table of Contents
On 12 August 2026 the OpenAI Python SDK shipped version 3.0.0 with exactly one breaking change, and sixteen days later the migration guide for it landed on the front page of Hacker News with 185 points and 78 comments as of 29 August 2026. That sixteen-day gap is the interesting part. The OpenAI Python HTTPX2 migration swapped httpx for httpx2, the Pydantic team's rewrite, which means pip install openai no longer installs httpx or certifi for you. Nothing warns you. Your lockfile resolves cleanly, and then something four levels down the dependency tree dies at import time.
Key Takeaways:
openai3.0.0 (12 August 2026) made HTTPX2 the default HTTP client; as of 3.6.0 the package requireshttpx2<3,>=2.7.0, where the 2.x line requiredhttpx<1,>=0.23.0certifiis no longer installed, and TLS verification now reads the operating system trust store instead of certifi's bundle- Anthropic's Python SDK made the same jump in v1.0.0 on 20 August 2026
- Two failure modes dominate:
ModuleNotFoundError: No module named 'httpx'at import, and mocked test suites silently escaping to the live API - Every version number and error string below was read from PyPI, the GitHub releases and the openai-python repository on 29 August 2026
What the OpenAI Python HTTPX2 Switch Actually Removed
The release notes are short enough to quote in full. Under BREAKING CHANGES: "HTTPX2 is now the default HTTP client, and httpx is no longer installed automatically." Applications passing custom HTTPX clients, transports or configuration objects have to migrate them, or reach for a temporary escape hatch that the guide is careful to describe as temporary.

Pull the metadata and the change is unambiguous. The openai 3.6.0 wheel on PyPI declares httpx2<3,>=2.7.0 in its requirements, alongside anyio, jiter, pydantic, sniffio and typing-extensions. The 2.x line declared httpx<1,>=0.23.0. There is no certifi in either list any more, and that second absence causes more trouble than the first, for reasons that take a while to surface.
If you build an OpenAI client the ordinary way, with no http_client argument, your calls keep working. Streaming, retries, parsed response models, numeric timeouts: unchanged. The blast radius is entirely in the layer around the SDK, which is exactly where nobody looks first.
The Two Errors You Will Actually See
The first one arrives immediately and is easy to read:
ModuleNotFoundError: No module named 'httpx'
Simon Willison's llm tool caught this on release day. The tool imports httpx in llm/models.py, llm/cli.py, llm/utils.py and llm/default_plugins/openai_models.py, but never declared it as a direct dependency, because for years it arrived free with openai. Since llm required openai>=2.32.0 with no upper bound, a clean resolve on 12 August pulled openai==3.0.0 and no httpx at all, so every command died at import.

The second error is stranger, and it costs money:
openai.AuthenticationError: Error code: 401 - {'error': {'message': 'Incorrect API key provided: test...
That one comes from a test suite, and it means the mocks stopped working. More on that below, because it deserves its own section.
Anthropic Shipped the Same Change Eight Days Later
This is not one vendor's decision. On 20 August 2026, anthropic-sdk-python released v1.0.0 with its own BREAKING CHANGES entry: "client: upgrade to httpx2 and some minor breaking changes." The 1.2.0 wheel currently on PyPI requires httpx2<3,>=2.0.0.

So if your service talks to both providers, and plenty do, you get two independent major-version bumps eight days apart, both pointing at the same new HTTP library. Anything in between that expected httpx objects, whether that's an auth handler, a tracing middleware or a proxy integration, now sits between two clients that no longer speak its dialect. We wrote about the npm side of this pattern in the AI SDK dependency wars; the Python version is tidier but lands harder, since Python has no equivalent of nested node_modules to let two versions coexist quietly.
certifi Is Gone and TLS Moved to the Operating System
Here is the paragraph in the migration guide that deserves more attention than it gets. HTTPX verified certificates against the CA bundle shipped by certifi. HTTPX2 reads the operating system trust store instead, and the SDK no longer installs certifi at all.

That breaks three specific situations, and the guide names them: minimal container images without system CA certificates, environments behind corporate TLS-inspecting proxies, and deployments that relied on a custom or patched certifi bundle. A python:3.12-slim image with no ca-certificates package used to work because certifi carried its own roots along. Now it doesn't, and the failure looks like a certificate problem rather than a dependency problem, which sends people down the wrong debugging path for an hour.
The documented fixes are environment variables, honoured while trust_env=True, which is the default:
export SSL_CERT_FILE=/path/to/ca-bundle.pem
export SSL_CERT_DIR=/path/to/ca-directory
Or you pass an explicit ssl.SSLContext through verify on a DefaultHttpx2Client. One user on the OpenAI developer forum framed the underlying question sharply: do you trust an OS vendor's certificate installation mechanism more than the Python supply chain? Reasonable people land on both sides of that. What isn't reasonable is finding out which side you're on from a production incident.
This is the class of problem that stops being yours when the environment is somebody else's job to keep current. MoClaw runs as a hosted cloud AI computer with a maintained system trust store, so a change in where Python looks for CA roots doesn't turn into an evening of openssl s_client output on your laptop.
The Expensive One: Mocked Tests Escaping to the Live API
The llm issue documented a second consequence that I'd rank as worse than the import error, because the import error is loud.
The project pinned pytest-httpx>=0.33.0 in its dev group, and pytest-httpx depends on httpx 0.28.*. Under openai 3.0.0, httpx_mock patches the legacy library while the SDK sends its requests through HTTPX2. The mock doesn't intercept anything. It doesn't error either; it just quietly fails to match, and the request goes out to the real API with whatever dummy credential the fixture supplied. The run went from 64 passing tests on openai 2.54.0 to 18 failures and 46 passes, and the failures were authentication errors from a live endpoint.
Substitute a real key for a dummy one, which is common enough in integration suites, and CI starts billing you for every run. RESPX users are in the same position: the guide states plainly that a RESPX version patching only legacy HTTPX cannot intercept the SDK's default HTTPX2 client. If your mocking layer went silent rather than red, you have no signal until the invoice arrives.
Slow, live-network test runs also stop being background noise the moment they're hitting a real endpoint. Running that suite somewhere that isn't your laptop, on a MoClaw instance that stays powered on, at least means a forty-minute investigation isn't also holding your machine hostage.
Getting Out: Two Real Options and One Escape Hatch
The clean fix is to stop relying on a transitive gift. If your code imports httpx, declare httpx in your own dependencies and keep using it, or move those imports to httpx2 and migrate the objects. The mapping is mechanical: httpx.Client to httpx2.Client, httpx.Timeout to httpx2.Timeout, httpx.HTTPTransport to httpx2.HTTPTransport, and so on down the list. Numeric timeout values and string URLs don't change at all.
Most teams hit by the OpenAI Python HTTPX2 change take this route first. The blunt fix is a pin, and there's precedent worth copying. On 21 August, llm shipped 0.32.1 whose entire release note was a pin to openai<3.0.0 so that fresh installs would work again. The real migration landed the next day in 0.33. Pinning bought them a day; treat it as a day, not a plan.
The escape hatch is documented but deliberately awkward. You install legacy HTTPX yourself and inject it:
from typing import Any, cast
import httpx
from openai import OpenAI
client = OpenAI(http_client=cast(Any, httpx.Client()))
Legacy support here is runtime-only. The SDK's public type annotations accept HTTPX2 clients, so passing a legacy client fails static type checking in mypy and Pyright, which is why the cast(Any, ...) is there. The guide also says this path "may be discontinued", which is about as clear a deprecation warning as you get before an actual deprecation notice. If you've been through the Assistants API wind-down, you know how much runway that phrasing usually buys.
None of this is an argument against running your own environment. It's an argument for not having only one. MoClaw sits alongside your local venv rather than replacing it, which is the useful shape when the thing that broke is the local venv.
Why It Took Sixteen Days to Bite
Transitive dependency changes propagate at the speed of other people's release cycles. openai 3.0.0 landed on 12 August; llm filed within hours because its maintainers upgrade fast. Most projects don't. They discover it when a colleague builds a fresh container, when Renovate opens a PR, or when a CI cache expires and the resolver picks something new. By 28 August enough of those had happened that httpx2.md reached the Hacker News front page two and a half weeks after the code that caused it.
The lesson from the OpenAI Python HTTPX2 rollout isn't "pin everything", which nobody does consistently anyway. It's that the SDK's own surface staying stable told you nothing about your blast radius. Your risk lived in the packages that quietly borrowed httpx from openai, and in the test doubles patching a library the SDK had stopped using. We hit a similar shape when OpenRouter's batch model IDs disappeared: the thing that broke wasn't the thing that changed.
Keeping an agent running on MoClaw while you untangle a lockfile is a small hedge, but it's the difference between a bad afternoon and a stopped one.
FAQ
Do I have to migrate to httpx2 to use the OpenAI Python SDK?
Not if you use the default client. Constructing OpenAI() or AsyncOpenAI() without an http_client argument keeps working, and HTTPX2 installs automatically with pip install openai. You only migrate if you pass custom clients, transports, timeouts, auth handlers or event hooks.
Why do I get ModuleNotFoundError: No module named 'httpx' after upgrading?
Because your code, or a package you depend on, imports httpx without declaring it. It used to arrive transitively through openai. As of 3.0.0 it doesn't. Add httpx to your own dependencies, or migrate those imports to httpx2.
Does the OpenAI Python HTTPX2 change affect certificate verification?
Yes, and this is the part most people miss. HTTPX2 uses the OS trust store rather than certifi's bundle, and certifi is no longer installed. Slim containers without ca-certificates, and networks with TLS-inspecting proxies, are the two environments most likely to break.
Will my pytest-httpx or RESPX mocks still work?
Not against the default client. Both patch legacy HTTPX, and the SDK now sends through HTTPX2, so requests pass straight through to the real API instead of failing loudly. Update to an HTTPX2-compatible version, or inject a legacy client in tests while you migrate.
Did Anthropic's Python SDK change too?
Yes. anthropic-sdk-python v1.0.0, released 20 August 2026, upgraded to httpx2 as its own breaking change, and the current 1.2.0 release requires httpx2<3,>=2.0.0.
What to Check Before Your Next Upgrade
Grep your tree for import httpx and check whether anything declares it. Look at what your test doubles patch, and whether that library is still the one your SDK uses. If you ship containers, confirm ca-certificates is installed rather than assuming certifi carried it. As of 29 August 2026 the escape hatch is still there, the pin still works, and neither is where you want to be in November.
Continue Reading
More GuideThe MoClaw editorial team writes about workflow automation, AI agents, and the tools we build. Default byline for industry overviews, listicles, and collaborative pieces.
Ready to put this into practice?
MoClaw runs browser tasks, research, and schedules automatically. Try it free.
References: openai-python v3.0.0 release notes (BREAKING CHANGES: HTTPX2) · OpenAI Python SDK: Migrating to HTTPX2 · simonw/llm #1608: Fresh install broken and test suite escapes to live API since openai 3.0.0 · anthropic-sdk-python v1.0.0 release notes (upgrade to httpx2) · openai on PyPI (dependency metadata) · Hacker News: OpenAI: Migrating to HTTPX2