Confirm this is a feature request for the Node library and not the underlying OpenAI API.
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=0 makes 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 ca to undici's Agent, it replaces the default trust store. You must combine your custom CA with tls.rootCertificates or public HTTPS endpoints will break.
-
Singleton dispatcher: Create the undici.Agent once 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 replaces globalThis.fetch. You must pass a custom fetch function that calls undici.fetch directly.
-
Lazy-load undici: undici v7 references File at the module level, which doesn't exist in Node.js 18. Use require() inside a function instead of a top-level import to 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_CERTS natively 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 than globalThis.fetch)
Related issues
Additional context
No response
Confirm this is a feature request for the Node library and not the underlying OpenAI API.
Describe the feature or improvement you're requesting
Describe the issue
The OpenAI SDK v5 uses
undiciinternally for HTTP requests.undici'sfetch()does not respectNODE_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=0works (confirming the endpoint is reachable), but this disables all TLS verification and is not acceptable for production.Environment
Steps to reproduce
NODE_EXTRA_CA_CERTS=/path/to/corporate-ca-chain.pemNODE_TLS_REJECT_UNAUTHORIZED=0makes it work, confirming the issue is with CA certificate loading, not connectivity.Root cause
The OpenAI SDK v5 uses
undicifor HTTP, andundici'sfetch()does not honorNODE_EXTRA_CA_CERTS(see nodejs/undici#2200). The SDK'sfetchOptions: { dispatcher }option also doesn't work in Next.js environments because Next.js patchesglobalThis.fetch, silently dropping the undicidispatcheroption.Workaround
The solution is to pass an explicit
fetchfunction usingundici.fetchdirectly (bypassing the patched global fetch) with a singleton dispatcher carrying the custom CA certificates: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:
NODE_EXTRA_CA_CERTSnatively by reading the env var and configuring its internal undici dispatcher automaticallyfetchOptions: { dispatcher }works reliably regardless of framework-level fetch patching (e.g., by using undici's fetch internally rather thanglobalThis.fetch)Related issues
fetch()ignores NODE_EXTRA_CA_CERTSAdditional context
No response