-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Confirm this is a feature request for the Node library and not the underlying OpenAI API.
- This is a feature request for the Node library
Describe the feature or improvement you're requesting
Describe the issue
The OpenAI SDK v5 uses undici internally for HTTP requests. undici's fetch() does not respect NODE_EXTRA_CA_CERTS (nodejs/undici#2200), which means enterprise users behind corporate TLS inspection proxies or connecting to endpoints with private CA certificates cannot establish connections.
Setting NODE_TLS_REJECT_UNAUTHORIZED=0 works (confirming the endpoint is reachable), but this disables all TLS verification and is not acceptable for production.
Environment
- openai SDK version: 5.20.2
- Node.js version: 22.x
- Framework: Next.js 14.x (server-side)
- OS: Linux (also reproduced on Windows/WSL2)
Steps to reproduce
- Set
NODE_EXTRA_CA_CERTS=/path/to/corporate-ca-chain.pem - Create an OpenAI client pointing to an endpoint with a certificate signed by the corporate CA:
const openai = new OpenAI({
apiKey: "...",
baseURL: "https://internal-llm-endpoint.example.com/v1/",
});
await openai.chat.completions.create({ ... });- The request fails with:
Error: Connection error.
cause: Error: unable to verify the first certificate
code: UNABLE_TO_VERIFY_LEAF_SIGNATURE
- Setting
NODE_TLS_REJECT_UNAUTHORIZED=0makes it work, confirming the issue is with CA certificate loading, not connectivity.
Root cause
The OpenAI SDK v5 uses undici for HTTP, and undici's fetch() does not honor NODE_EXTRA_CA_CERTS (see nodejs/undici#2200). The SDK's fetchOptions: { dispatcher } option also doesn't work in Next.js environments because Next.js patches globalThis.fetch, silently dropping the undici dispatcher option.
Workaround
The solution is to pass an explicit fetch function using undici.fetch directly (bypassing the patched global fetch) with a singleton dispatcher carrying the custom CA certificates:
import { OpenAI } from "openai";
import * as fs from "fs";
import * as tls from "tls";
// Load custom CA and combine with Node.js root certificates
const customCaPath = process.env.NODE_EXTRA_CA_CERTS;
const customCa = customCaPath ? fs.readFileSync(customCaPath) : undefined;
const combinedCa = customCa ? [...tls.rootCertificates, customCa] : undefined;
// Lazy-load undici to avoid "File is not defined" during Next.js build on Node.js 18
let _dispatcher: any;
let _fetch: any;
let _initialized = false;
function ensureUndici() {
if (_initialized) return;
_initialized = true;
if (!combinedCa) return;
const undici = require("undici");
_dispatcher = new undici.Agent({ connect: { ca: combinedCa } });
_fetch = undici.fetch;
}
// When creating the client:
ensureUndici();
const openai = new OpenAI({
apiKey: "...",
baseURL: "https://internal-llm-endpoint.example.com/v1/",
fetch: _dispatcher
? async (url, init) => {
return _fetch(url, { ...init, dispatcher: _dispatcher });
}
: undefined,
});Key details for the workaround
-
Combine CAs: When providing
cato undici'sAgent, it replaces the default trust store. You must combine your custom CA withtls.rootCertificatesor public HTTPS endpoints will break. -
Singleton dispatcher: Create the
undici.Agentonce and reuse it. Creating a new one per request defeats connection pooling. -
Explicit undici fetch: Passing
fetchOptions: { dispatcher }does NOT work in Next.js because Next.js replacesglobalThis.fetch. You must pass a customfetchfunction that callsundici.fetchdirectly. -
Lazy-load undici:
undiciv7 referencesFileat the module level, which doesn't exist in Node.js 18. Userequire()inside a function instead of a top-levelimportto avoid build failures. -
Full CA chain: The PEM file must contain the full CA chain (intermediate + root CAs), not the server's leaf certificate.
Suggestion
It would be helpful if the OpenAI SDK could:
- Respect
NODE_EXTRA_CA_CERTSnatively by reading the env var and configuring its internal undici dispatcher automatically - Document the workaround for enterprise users who need custom CA certificates
- Ensure
fetchOptions: { dispatcher }works reliably regardless of framework-level fetch patching (e.g., by using undici's fetch internally rather thanglobalThis.fetch)
Related issues
- nodejs/undici#2200 —
fetch()ignores NODE_EXTRA_CA_CERTS - openai/openai-node#1555 — fetchOptions dispatcher type error (fixed in v5.8.2)
- cline/cline#8816 — Custom CA certs not respected for API connections
Additional context
No response