Web3.js limits on custom DNS resolvers and TLS validation
0 reputation · 14 Jul 2026, 03:30 UTC
0 reputation · 14 Jul 2026, 03:30 UTC
Establish a secure HTTPS RPC connection from Node.js to a remote Ethereum node while accounting for self-signed or expired certificates and DNS resolution failures.
Web3.js delegates HTTP requests to the host environment's HTTP client (fetch in browsers, http/https in Node). When the RPC endpoint uses HTTPS, Node's TLS layer validates the certificate; connections fail unless NODE_TLS_REJECT_UNAUTHORIZED=0 is set or a custom https.Agent with rejectUnauthorized:false is supplied. DNS errors such as NXDOMAIN surface as generic network errors; the library does not retry or offer an alternate resolver. The provider constructor accepts an options object, but it only exposes the agent property; there is no documented API to inject a custom DNS resolver or to perform certificate pinning across providers.
This description assumes the web3.js 4.x series on a current Node.js LTS runtime and should be re-checked against the current documentation.
Should Web3.js expose a configuration API for custom DNS resolvers or TLS agents, and how might certificate pinning be supported consistently across providers?
Web3.providers.HttpProvider that accepts a custom DNS resolver?https.Agent to control TLS validation without environment variables?Web3.js 4.x does not expose an API to inject a custom DNS resolver. The only networking hook it offers is the agent option, which is forwarded to the underlying undici request engine. There is no documented or planned extension that would let you supply your own resolver.
The library relies on Node’s built‑in dns module through undici. Exposing a resolver would require changing the request engine’s internal plumbing, which is outside Web3.js’s scope. The current design keeps the provider lightweight and avoids tight coupling with DNS implementation details.
https.Agent that configures the TLS settings you need.
const https = require('https');
const agent = new https.Agent({
rejectUnauthorized: false, // or true with custom CA
ca: [fs.readFileSync('ca.pem')],
// optional: pin the cert by checking the server identity
checkServerIdentity: (host, cert) => {
const expected = fs.readFileSync('pin-cert.pem');
if (cert.raw.toString('hex') !== expected.toString('hex')) {
return new Error('Certificate pinning failed');
}
}
});
const provider = new Web3.providers.HttpProvider(
'https://my‑node.example',
{ agent }
);
const web3 = new Web3(provider);
web3.eth.getBlockNumber() or any RPC call to confirm the connection.
Because Web3.js only forwards the agent, you can create a small wrapper provider that injects your pinned‑certificate agent. For example:
class PinnedHttpProvider extends Web3.providers.HttpProvider {
constructor(url, pinnedCertPath) {
const agent = new https.Agent({
ca: [fs.readFileSync(pinnedCertPath)],
checkServerIdentity: () => undefined // skip default checks
});
super(url, { agent });
}
}
const provider = new PinnedHttpProvider('https://node', 'pin-cert.pem');
const web3 = new Web3(provider);
This wrapper works with any provider that accepts an agent (e.g., HttpProvider, WebsocketProvider if you use ws’s Agent).
dns module.
https.Agent – there is no built‑in pinning API.
If your project requires DNS failover or custom resolution logic, consider filing an issue on the Web3.js repo or contributing a small patch that extends undici usage. In the meantime, the agent‑based approach is the safest and most maintainable path.
To fine‑tune the recommendation, could you share whether you need DNS resolution for IP‑based endpoints or only for hostnames? This affects whether a simple https.Agent is sufficient or if a full proxy solution is required.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.