How to Use Proxies with Node.js Axios in 2026: Complete Guide
Axios is the most popular HTTP client for Node.js, used by millions of developers for API calls, web scraping, and server-to-server communication. While Axios has a built-in proxy option, the real world of proxy integration is more nuanced — especially when dealing with HTTPS, SOCKS5, authentication, and rotation.
This guide covers every proxy configuration method for Axios, from the basics to production-grade patterns with TypeScript, with working code you can use immediately.
Why Use Proxies with Axios?
When your Node.js application makes HTTP requests, the target server sees your server’s IP address. This creates problems at scale:
- API rate limits — services throttle requests from a single IP
- IP blocking — aggressive scraping leads to permanent bans
- Geo-restrictions — content varies by geographic location
- Competitive intelligence — you do not want targets to know your infrastructure IP
Proxies route requests through intermediate servers, masking your real IP and enabling rotation. Use our proxy cost calculator to estimate costs for your project.
Prerequisites
- Node.js 18+ (LTS recommended)
- npm or yarn
npm init -y
npm install axiosFor HTTPS and SOCKS proxy support:
npm install https-proxy-agent http-proxy-agent socks-proxy-agentBasic Proxy Configuration
Axios Built-In Proxy Option
Axios has a native proxy configuration for HTTP proxies:
const axios = require('axios');
const response = await axios.get('http://httpbin.org/ip', {
proxy: {
host: 'proxy.example.com',
port: 8080
}
});
console.log(response.data);Critical limitation: The built-in proxy option only works for HTTP requests, not HTTPS. For HTTPS targets (which is most of the web in 2026), you need an agent-based approach.
Authenticated HTTP Proxy
const axios = require('axios');
const response = await axios.get('http://httpbin.org/ip', {
proxy: {
host: 'proxy.example.com',
port: 8080,
auth: {
username: 'your_username',
password: 'your_password'
}
}
});
console.log(response.data);HTTPS Proxies with Agent Libraries
For HTTPS requests through a proxy (the standard case), use proxy agent libraries:
Using https-proxy-agent
npm install https-proxy-agentconst axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');
const agent = new HttpsProxyAgent('http://username:password@proxy.example.com:8080');
const response = await axios.get('https://httpbin.org/ip', {
httpsAgent: agent
});
console.log(response.data);
// { "origin": "proxy.ip.address" }Using http-proxy-agent for HTTP Targets
npm install http-proxy-agentconst axios = require('axios');
const { HttpProxyAgent } = require('http-proxy-agent');
const agent = new HttpProxyAgent('http://username:password@proxy.example.com:8080');
const response = await axios.get('http://httpbin.org/ip', {
httpAgent: agent
});
console.log(response.data);Combined HTTP and HTTPS Agent Setup
const axios = require('axios');
const { HttpProxyAgent } = require('http-proxy-agent');
const { HttpsProxyAgent } = require('https-proxy-agent');
const proxyUrl = 'http://username:password@proxy.example.com:8080';
const client = axios.create({
httpAgent: new HttpProxyAgent(proxyUrl),
httpsAgent: new HttpsProxyAgent(proxyUrl)
});
// Works for both HTTP and HTTPS targets
const httpResponse = await client.get('http://httpbin.org/ip');
const httpsResponse = await client.get('https://httpbin.org/ip');
console.log('HTTP:', httpResponse.data);
console.log('HTTPS:', httpsResponse.data);SOCKS Proxy Support
Using socks-proxy-agent
npm install socks-proxy-agentconst axios = require('axios');
const { SocksProxyAgent } = require('socks-proxy-agent');
// SOCKS5 proxy
const agent = new SocksProxyAgent('socks5://username:password@proxy.example.com:1080');
const response = await axios.get('https://httpbin.org/ip', {
httpAgent: agent,
httpsAgent: agent
});
console.log(response.data);SOCKS5h (Remote DNS Resolution)
const agent = new SocksProxyAgent('socks5h://username:password@proxy.example.com:1080');Using socks5h:// ensures DNS lookups happen on the proxy server, preventing DNS leaks.
Axios Interceptors for Proxy Rotation
Axios interceptors let you modify every request before it is sent. This is perfect for proxy rotation:
Basic Rotation Interceptor
const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');
const proxies = [
'http://user:pass@proxy1.example.com:8080',
'http://user:pass@proxy2.example.com:8080',
'http://user:pass@proxy3.example.com:8080',
'http://user:pass@proxy4.example.com:8080',
'http://user:pass@proxy5.example.com:8080',
];
let proxyIndex = 0;
const client = axios.create();
client.interceptors.request.use((config) => {
const proxyUrl = proxies[proxyIndex % proxies.length];
proxyIndex++;
config.httpsAgent = new HttpsProxyAgent(proxyUrl);
config.proxy = false; // Disable built-in proxy to use agent
return config;
});
// Each request uses a different proxy
const results = await Promise.all([
client.get('https://httpbin.org/ip'),
client.get('https://httpbin.org/ip'),
client.get('https://httpbin.org/ip'),
]);
results.forEach((r, i) => console.log(`Request ${i + 1}:`, r.data));Random Rotation Interceptor
const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');
const proxies = [
'http://user:pass@proxy1.example.com:8080',
'http://user:pass@proxy2.example.com:8080',
'http://user:pass@proxy3.example.com:8080',
];
const client = axios.create();
client.interceptors.request.use((config) => {
const randomProxy = proxies[Math.floor(Math.random() * proxies.length)];
config.httpsAgent = new HttpsProxyAgent(randomProxy);
config.proxy = false;
return config;
});Geo-Targeted Interceptor
const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');
const geoProxies = {
us: 'http://user:pass@us-proxy.example.com:8080',
uk: 'http://user:pass@uk-proxy.example.com:8080',
de: 'http://user:pass@de-proxy.example.com:8080',
jp: 'http://user:pass@jp-proxy.example.com:8080',
};
function createGeoClient(country) {
const proxyUrl = geoProxies[country];
if (!proxyUrl) throw new Error(`No proxy for country: ${country}`);
return axios.create({
httpsAgent: new HttpsProxyAgent(proxyUrl),
proxy: false
});
}
const usClient = createGeoClient('us');
const ukClient = createGeoClient('uk');
const [usResult, ukResult] = await Promise.all([
usClient.get('https://httpbin.org/ip'),
ukClient.get('https://httpbin.org/ip'),
]);
console.log('US IP:', usResult.data);
console.log('UK IP:', ukResult.data);Error Handling and Retry with axios-retry
Install axios-retry
npm install axios-retryBasic Retry Configuration
const axios = require('axios');
const axiosRetry = require('axios-retry').default;
const { HttpsProxyAgent } = require('https-proxy-agent');
const client = axios.create({
httpsAgent: new HttpsProxyAgent('http://user:pass@proxy.example.com:8080'),
proxy: false,
timeout: 15000
});
axiosRetry(client, {
retries: 3,
retryDelay: axiosRetry.exponentialDelay,
retryCondition: (error) => {
// Retry on network errors and 5xx responses
return axiosRetry.isNetworkOrIdempotentRequestError(error)
|| (error.response && error.response.status >= 500)
|| (error.response && error.response.status === 429);
},
onRetry: (retryCount, error) => {
console.log(`Retry ${retryCount}: ${error.message}`);
}
});
const response = await client.get('https://httpbin.org/ip');
console.log(response.data);Retry with Proxy Rotation on Failure
const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');
const proxies = [
'http://user:pass@proxy1.example.com:8080',
'http://user:pass@proxy2.example.com:8080',
'http://user:pass@proxy3.example.com:8080',
];
async function fetchWithRetry(url, maxRetries = 3) {
const shuffled = [...proxies].sort(() => Math.random() - 0.5);
for (let attempt = 0; attempt < maxRetries; attempt++) {
const proxyUrl = shuffled[attempt % shuffled.length];
try {
const response = await axios.get(url, {
httpsAgent: new HttpsProxyAgent(proxyUrl),
proxy: false,
timeout: 10000
});
if (response.status === 200) {
return response.data;
}
} catch (error) {
const msg = error.response
? `HTTP ${error.response.status}`
: error.message;
console.warn(`Attempt ${attempt + 1}/${maxRetries} [${proxyUrl}]: ${msg}`);
}
// Exponential backoff
if (attempt < maxRetries - 1) {
const delay = Math.min(1000 * Math.pow(2, attempt), 8000);
await new Promise(resolve => setTimeout(resolve, delay));
}
}
throw new Error(`All ${maxRetries} attempts failed for ${url}`);
}
// Usage
const data = await fetchWithRetry('https://httpbin.org/ip');
console.log(data);Proxy Pool Implementation
A production proxy pool tracks proxy health and routes requests to healthy proxies:
const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');
class ProxyPool {
constructor(proxyUrls) {
this.proxies = proxyUrls.map(url => ({
url,
failures: 0,
lastUsed: 0,
totalRequests: 0,
successRate: 1.0
}));
this.maxFailures = 5;
this.cooldownMs = 30000;
}
getProxy() {
const now = Date.now();
const available = this.proxies.filter(
p => p.failures < this.maxFailures && (now - p.lastUsed > 500)
);
if (available.length === 0) {
// Reset all proxies and try again
this.proxies.forEach(p => { p.failures = 0; });
return this.proxies[0];
}
// Prefer proxies with better success rates
available.sort((a, b) => b.successRate - a.successRate);
const proxy = available[0];
proxy.lastUsed = now;
proxy.totalRequests++;
return proxy;
}
reportSuccess(proxy) {
proxy.failures = Math.max(0, proxy.failures - 1);
proxy.successRate = proxy.successRate * 0.9 + 0.1;
}
reportFailure(proxy) {
proxy.failures++;
proxy.successRate = proxy.successRate * 0.9;
}
getStats() {
return this.proxies.map(p => ({
url: p.url.replace(/\/\/.*@/, '//***@'), // Hide credentials
failures: p.failures,
requests: p.totalRequests,
successRate: (p.successRate * 100).toFixed(1) + '%'
}));
}
}
// Usage
const pool = new ProxyPool([
'http://user:pass@proxy1.example.com:8080',
'http://user:pass@proxy2.example.com:8080',
'http://user:pass@proxy3.example.com:8080',
'http://user:pass@proxy4.example.com:8080',
'http://user:pass@proxy5.example.com:8080',
]);
async function fetchUrl(url) {
const proxyInfo = pool.getProxy();
try {
const response = await axios.get(url, {
httpsAgent: new HttpsProxyAgent(proxyInfo.url),
proxy: false,
timeout: 10000
});
pool.reportSuccess(proxyInfo);
return response.data;
} catch (error) {
pool.reportFailure(proxyInfo);
throw error;
}
}
// Scrape multiple URLs
const urls = Array.from({ length: 20 }, (_, i) => `https://httpbin.org/anything/${i}`);
const results = [];
for (const url of urls) {
try {
const data = await fetchUrl(url);
results.push({ url, status: 'success' });
} catch (err) {
results.push({ url, status: 'failed', error: err.message });
}
}
console.log(`Success: ${results.filter(r => r.status === 'success').length}/${results.length}`);
console.log('Pool stats:', pool.getStats());Concurrent Requests with Proxy Rotation
const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');
async function scrapeWithConcurrency(urls, proxies, concurrency = 5) {
const results = new Array(urls.length);
let index = 0;
async function worker() {
while (index < urls.length) {
const currentIndex = index++;
const url = urls[currentIndex];
const proxyUrl = proxies[currentIndex % proxies.length];
try {
const response = await axios.get(url, {
httpsAgent: new HttpsProxyAgent(proxyUrl),
proxy: false,
timeout: 10000
});
results[currentIndex] = { url, status: response.status, data: response.data };
} catch (err) {
results[currentIndex] = { url, error: err.message };
}
}
}
const workers = Array.from({ length: concurrency }, () => worker());
await Promise.all(workers);
return results;
}
// Usage
const urls = Array.from({ length: 50 }, (_, i) => `https://httpbin.org/anything/${i}`);
const proxies = [
'http://user:pass@proxy1.example.com:8080',
'http://user:pass@proxy2.example.com:8080',
'http://user:pass@proxy3.example.com:8080',
];
const results = await scrapeWithConcurrency(urls, proxies, 5);
const successful = results.filter(r => !r.error).length;
console.log(`Completed: ${successful}/${results.length} successful`);TypeScript Examples
Type-Safe Proxy Configuration
import axios, { AxiosInstance, AxiosRequestConfig, InternalAxiosRequestConfig } from 'axios';
import { HttpsProxyAgent } from 'https-proxy-agent';
interface ProxyConfig {
host: string;
port: number;
username: string;
password: string;
protocol: 'http' | 'https' | 'socks5';
}
interface ProxyPoolConfig {
proxies: ProxyConfig[];
maxFailures: number;
rotationStrategy: 'round-robin' | 'random' | 'least-used';
}
function proxyConfigToUrl(config: ProxyConfig): string {
return `${config.protocol}://${config.username}:${config.password}@${config.host}:${config.port}`;
}
function createProxiedClient(proxyConfig: ProxyConfig): AxiosInstance {
const proxyUrl = proxyConfigToUrl(proxyConfig);
return axios.create({
httpsAgent: new HttpsProxyAgent(proxyUrl),
proxy: false,
timeout: 15000,
headers: {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/124.0.0.0',
},
});
}
// Usage
const proxy: ProxyConfig = {
host: 'proxy.example.com',
port: 8080,
username: 'user',
password: 'pass',
protocol: 'http',
};
const client = createProxiedClient(proxy);
const response = await client.get<{ origin: string }>('https://httpbin.org/ip');
console.log('IP:', response.data.origin);TypeScript Proxy Rotation Class
import axios, { AxiosInstance, AxiosResponse } from 'axios';
import { HttpsProxyAgent } from 'https-proxy-agent';
interface ProxyState {
url: string;
failures: number;
lastUsed: number;
requestCount: number;
}
class TypedProxyRotator {
private proxies: ProxyState[];
private index: number = 0;
constructor(proxyUrls: string[]) {
this.proxies = proxyUrls.map(url => ({
url,
failures: 0,
lastUsed: 0,
requestCount: 0,
}));
}
private getNextProxy(): ProxyState {
const proxy = this.proxies[this.index % this.proxies.length];
this.index++;
proxy.lastUsed = Date.now();
proxy.requestCount++;
return proxy;
}
async fetch<T = unknown>(url: string): Promise<T> {
const maxAttempts = Math.min(3, this.proxies.length);
for (let attempt = 0; attempt < maxAttempts; attempt++) {
const proxy = this.getNextProxy();
try {
const response: AxiosResponse<T> = await axios.get(url, {
httpsAgent: new HttpsProxyAgent(proxy.url),
proxy: false,
timeout: 10000,
});
proxy.failures = 0;
return response.data;
} catch (error) {
proxy.failures++;
console.warn(
`Attempt ${attempt + 1}/${maxAttempts} failed via ${proxy.url}: ${
error instanceof Error ? error.message : 'Unknown error'
}`
);
}
}
throw new Error(`All ${maxAttempts} proxy attempts failed for ${url}`);
}
}
// Usage
const rotator = new TypedProxyRotator([
'http://user:pass@proxy1.example.com:8080',
'http://user:pass@proxy2.example.com:8080',
'http://user:pass@proxy3.example.com:8080',
]);
interface IpResponse {
origin: string;
}
const data = await rotator.fetch<IpResponse>('https://httpbin.org/ip');
console.log('IP:', data.origin);Environment Variable Proxy Configuration
Axios respects the standard HTTP_PROXY and HTTPS_PROXY environment variables when the built-in proxy option is not set:
export HTTP_PROXY="http://user:pass@proxy.example.com:8080"
export HTTPS_PROXY="http://user:pass@proxy.example.com:8080"
export NO_PROXY="localhost,127.0.0.1"const axios = require('axios');
// Axios reads environment variables automatically
const response = await axios.get('https://httpbin.org/ip');
console.log(response.data);Note: If you set proxy: false in Axios config, environment variables are ignored. Remove the proxy key entirely to use env vars.
Troubleshooting Common Issues
Axios Proxy Option Does Not Work for HTTPS
Cause: The built-in proxy config only works for HTTP requests.
Fix: Use https-proxy-agent:
const { HttpsProxyAgent } = require('https-proxy-agent');
const response = await axios.get('https://example.com', {
httpsAgent: new HttpsProxyAgent('http://user:pass@proxy:8080'),
proxy: false // Disable built-in proxy
});Error: ECONNREFUSED or ECONNRESET
Cause: The proxy server refused the connection or reset it.
Fix:
- Verify the proxy is online
- Check that your IP is whitelisted with the proxy provider
- Reduce concurrent requests (you may be exceeding connection limits)
Error: SELF_SIGNED_CERT_IN_CHAIN
Cause: The proxy uses a self-signed certificate or does SSL interception.
Fix:
const agent = new HttpsProxyAgent('http://proxy:8080', {
rejectUnauthorized: false // Development only!
});For production, add the CA certificate:
const fs = require('fs');
const agent = new HttpsProxyAgent('http://proxy:8080', {
ca: fs.readFileSync('/path/to/ca-cert.pem')
});Request Hangs Indefinitely
Cause: No timeout configured and the proxy connection stalls.
Fix: Always set a timeout:
const response = await axios.get(url, {
httpsAgent: agent,
proxy: false,
timeout: 15000 // 15 seconds
});Memory Leak with Many Proxy Agents
Cause: Creating a new HttpsProxyAgent for every request without reusing them.
Fix: Cache agents per proxy URL:
const agentCache = new Map();
function getAgent(proxyUrl) {
if (!agentCache.has(proxyUrl)) {
agentCache.set(proxyUrl, new HttpsProxyAgent(proxyUrl));
}
return agentCache.get(proxyUrl);
}Proxy Works in cURL but Not Axios
Cause: Axios may be reading conflicting environment variables or the agent setup is wrong.
Fix:
- Check
process.env.HTTP_PROXYandprocess.env.HTTPS_PROXY - Explicitly set
proxy: falsewhen using an agent - Use verbose logging:
axios.interceptors.request.use(config => { console.log(config); return config; })
Summary
Axios proxy integration requires understanding the distinction between its built-in proxy option (HTTP only) and agent-based proxying (HTTPS and SOCKS5). Key points:
| Method | Use Case |
|---|---|
Built-in proxy config | HTTP targets only |
https-proxy-agent | HTTPS targets through HTTP proxy |
socks-proxy-agent | SOCKS4/SOCKS5 proxies |
| Axios interceptors | Proxy rotation per request |
axios-retry | Automatic retry with backoff |
| Agent caching | Performance optimization |
For production scraping and data collection, combine proxy pools, health tracking, retry logic, and concurrency control. Estimate your bandwidth needs with the proxy cost calculator and test your request fingerprint with the browser fingerprint tester.
- How to Use Proxies with cURL in 2026: Complete Guide
- How to Use Proxies with Playwright in 2026: Complete Guide
- Best Proxies for Amazon 2026: Complete Guide
- Best Proxies for Discord 2026: Bot Hosting & Account Management
- Best Proxies for eBay 2026: Complete Guide
- Best Proxies for Netflix 2026: Geo-Unblocking & Catalog Access
- How to Use Proxies with cURL in 2026: Complete Guide
- How to Use Proxies with Playwright in 2026: Complete Guide
- Best Proxies for Amazon 2026: Complete Guide
- Best Proxies for Discord 2026: Bot Hosting & Account Management
- Best Proxies for eBay 2026: Complete Guide
- Best Proxies for Netflix 2026: Geo-Unblocking & Catalog Access
- How to Use Proxies with cURL in 2026: Complete Guide
- How to Use Proxies with Playwright in 2026: Complete Guide
- Best Proxies for Amazon 2026: Complete Guide
- Best Proxies for Discord 2026: Bot Hosting & Account Management
- Best Proxies for eBay 2026: Complete Guide
- Best Proxies for Netflix 2026: Geo-Unblocking & Catalog Access
Related Reading
- How to Use Proxies with cURL in 2026: Complete Guide
- How to Use Proxies with Playwright in 2026: Complete Guide
- Best Proxies for Amazon 2026: Complete Guide
- Best Proxies for Discord 2026: Bot Hosting & Account Management
- Best Proxies for eBay 2026: Complete Guide
- Best Proxies for Netflix 2026: Geo-Unblocking & Catalog Access