How Proxy Support Functions in Uptime Kuma Monitors: HTTP, HTTPS, and SOCKS Implementation

Uptime Kuma routes monitor traffic through user-defined proxies by storing proxy configurations in SQLite, creating protocol-specific Node.js agents, and injecting those agents into Axios request options during health checks.

Uptime Kuma, the popular self-hosted uptime monitoring tool by louislam/uptime-kuma, provides robust proxy support that allows HTTP-based monitors to route checks through intermediary servers. This capability is essential for monitoring services behind corporate firewalls, geographic restrictions, or privacy layers. The proxy subsystem spans three architectural layers: the data persistence layer, the proxy management service, and the monitor execution engine.

Architecture of the Proxy Subsystem

The proxy implementation in Uptime Kuma follows a clear separation of concerns across the backend stack. Understanding these layers helps diagnose routing issues and customize proxy behavior.

Data Model and Persistence Layer

Proxy definitions reside in the proxy table, defined in server/model/proxy.js. This bean model stores the protocol type, host, port, authentication credentials, and active status. The database schema adds a proxy_id foreign key to the monitor table (defined in db/knex_init_db.js around line 96), establishing the relationship between monitors and their assigned proxies.

When you create or edit a proxy via the web interface, the proxySocketHandler in server/socket-handlers/proxy-socket-handler.js processes the request and invokes Proxy.save():

// server/proxy.js – validation & persistence
static async save(proxy, proxyID, userID) {
    // Validate supported protocols
    if (!this.SUPPORTED_PROXY_PROTOCOLS.includes(proxy.protocol)) {
        throw new Error(`Unsupported proxy protocol "${proxy.protocol}"`);
    }

    // Persist configuration
    bean.protocol = proxy.protocol;
    bean.host     = proxy.host;
    bean.port     = proxy.port;
    bean.auth     = proxy.auth;
    bean.username = proxy.username;
    bean.password = proxy.password;
    bean.active   = proxy.active || true;
    
    await R.store(bean);
}

Protocol-Specific Agent Creation

The Proxy.createAgents() method in server/proxy.js (lines 91-152) instantiates the appropriate Node.js agents based on the configured protocol. Uptime Kuma supports HTTP, HTTPS, and SOCKS variants (SOCKS4, SOCKS5, SOCKS5H) using specialized agent libraries wrapped with cookie-handling capabilities.

For HTTP and HTTPS proxies, the system creates separate agents for each protocol:

// server/proxy.js – HTTP/HTTPS agent creation
case "http":
case "https":
    const HttpCookieProxyAgent = createCookieAgent(HttpProxyAgent);
    const HttpsCookieProxyAgent = createCookieAgent(HttpsProxyAgent);
    httpAgent  = new HttpCookieProxyAgent(proxyUrl.toString(),
               { ...httpAgentOptions, cookies: { jar } });
    httpsAgent = new HttpsCookieProxyAgent(proxyUrl.toString(),
               { ...httpsAgentOptions, cookies: { jar } });
    break;

For SOCKS proxies, a single agent handles both HTTP and HTTPS traffic:

// server/proxy.js – SOCKS agent creation
case "socks":
case "socks5":
case "socks5h":
case "socks4":
    const SocksCookieProxyAgent = createCookieAgent(SocksProxyAgent);
    const agent = new SocksCookieProxyAgent(proxyUrl.toString(),
               { ...httpAgentOptions, ...httpsAgentOptions,
                 tls: { rejectUnauthorized: httpsAgentOptions.rejectUnauthorized } });
    httpAgent = httpsAgent = agent;
    break;

Monitor Integration During Health Checks

When a monitor executes its check cycle, the Monitor.start() method in server/model/monitor.js determines whether to use a proxy by checking the this.proxy_id property.

Injecting Proxies into Axios Requests

If a monitor has an associated proxy, the system loads the proxy bean and generates fresh agents for that request:

// server/model/monitor.js – proxy handling inside Monitor.start()
if (this.proxy_id) {
    const proxy = await R.load("proxy", this.proxy_id);
    if (proxy && proxy.active) {
        const { httpAgent, httpsAgent } = Proxy.createAgents(proxy, {
            httpsAgentOptions,
            httpAgentOptions,
        });

        // Disable Axios built-in proxy handling to use custom agents
        options.proxy = false;
        options.httpAgent  = httpAgent;
        options.httpsAgent = httpsAgent;
    }
}

Setting options.proxy = false is critical because it prevents Axios from attempting to use its internal proxy logic, ensuring the request routes exclusively through the custom agents. This approach supports cookie persistence and TLS certificate validation options that pure Axios proxy configuration cannot handle.

Global Proxy Management and Synchronization

Uptime Kuma provides utilities for applying proxy changes across multiple monitors without manual reconfiguration.

Reloading Proxy Associations

The Proxy.reloadProxy() method synchronizes the in-memory monitor list with database changes:

// server/proxy.js – synchronize proxy assignments
static async reloadProxy() {
    const server = UptimeKumaServer.getInstance();
    const updatedList = await R.getAssoc("SELECT id, proxy_id FROM monitor");
    for (let monitorID in server.monitorList) {
        const monitor = server.monitorList[monitorID];
        if (updatedList[monitorID]) {
            monitor.proxy_id = updatedList[monitorID].proxy_id;
        }
    }
}

When you mark a proxy as default or set the applyExisting flag, Proxy.applyProxyEveryMonitor updates all monitors for that user, then calls reloadProxy() to refresh the running monitor instances without requiring a server restart.

Summary

  • Three-layer architecture: The proxy system combines server/model/proxy.js for data, server/proxy.js for business logic, and server/model/monitor.js for execution.
  • Protocol support: HTTP, HTTPS, SOCKS4, SOCKS5, and SOCKS5H proxies are supported with cookie-aware agents.
  • Axios integration: Monitors inject custom httpAgent and httpsAgent instances while disabling native Axios proxy handling via options.proxy = false.
  • Dynamic reloading: The reloadProxy() method updates running monitors when global proxy settings change, ensuring zero-downtime configuration updates.
  • Authentication: Username/password credentials are embedded in the proxy URL when proxy.auth is enabled, supporting authenticated corporate proxies.

Frequently Asked Questions

What proxy protocols does Uptime Kuma support?

Uptime Kuma supports HTTP, HTTPS, SOCKS4, SOCKS5, and SOCKS5H protocols. The SUPPORTED_PROXY_PROTOCOLS array in server/proxy.js validates these values during proxy creation. SOCKS proxies use the socks-proxy-agent library, while HTTP/HTTPS proxies use http-proxy-agent and https-proxy-agent wrapped with cookie-handling decorators.

How does Uptime Kuma handle proxy authentication?

When a proxy has auth set to true, Uptime Kuma embeds credentials directly into the proxy URL constructed in Proxy.createAgents(). The username and password from the proxy configuration are assigned to proxyUrl.username and proxyUrl.password before instantiating the agent. This method securely passes authentication to the underlying proxy agent libraries without exposing credentials in Axios logs.

Can I apply a proxy to multiple monitors at once?

Yes. The Proxy.applyProxyEveryMonitor method updates the proxy_id for all monitors belonging to the user when you set a proxy as default or enable the applyExisting flag. After database updates, Proxy.reloadProxy() synchronizes the in-memory monitor list, applying changes immediately without requiring individual monitor edits or server restarts.

Does Uptime Kuma use Axios built-in proxy settings?

No. Uptime Kuma explicitly disables Axios's native proxy handling by setting options.proxy = false in the monitor's request configuration. Instead, it provides custom httpAgent and httpsAgent instances created by Proxy.createAgents(). This approach provides finer control over TLS options, cookie jars, and connection pooling than Axios's built-in proxy configuration allows.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →