Skip to content
Fixedmark
Integration · Serverless and edge functions

Cloudflare Workers Static IP: What Works

Cloudflare Workers cannot send `fetch` through an HTTP or SOCKS5 proxy, so Fixedmark cannot give a Worker a static IP directly. The pattern that works is a small relay on Railway, Render, Fly.io, or Cloud Run: the Worker calls the relay, and the relay calls the partner through your dedicated IP pair.

Why Workers have no fixed IP, and why a proxy does not help

Workers run in every Cloudflare data center. Subrequests leave from Cloudflare's own network and the address depends on where the Worker ran.

Other runtimes fix this with a proxy setting on the HTTP client. Workers' fetch has no such setting: you cannot pass an agent, a dispatcher, or a proxy URL. Workers do offer outbound TCP through connect(), which can upgrade a plain socket to TLS once with startTls(). That rules out the TLS-wrapped HTTPS proxy, which needs TLS to the proxy and then a second TLS session to the destination inside it. A SOCKS5 handshake over a plain socket followed by startTls() fits the API in principle, but you would write HTTP/1.1 by hand and send proxy credentials unencrypted. We have not tested it and do not support it at launch.

Cloudflare's own options

Cloudflare's Dedicated CDN Egress IPs are an Enterprise add-on with no public price. Per Cloudflare's docs, Workers fetch to services on your origin uses them, and connect() does not. Cloudflare Gateway also has dedicated egress IPs on Enterprise, and the Workers VPC beta can send Worker traffic to the internet through Gateway. Cloudflare does not document whether that path uses Gateway's dedicated egress IPs, so confirm with Cloudflare before you rely on it. There is no self-serve static egress setting for Workers.

Sources for Cloudflare Workers pricing

Checked October 2026. Confirm current details on the vendor's site before you decide. Prices and limits change.

Set up a static IP on Cloudflare Workers

The relay is a few dozen lines. Keep it narrow: it forwards fixed paths to one partner and requires a shared secret, so it never becomes an open proxy.

Fixedmark is in early access. Proxy URLs are issued at launch. Join early access to get yours when your region opens.

Before you start

  • A Worker and Wrangler, logged in.
  • An account on a platform that can run a small Node.js service: Railway, Render, Fly.io, or Cloud Run.
  • A Fixedmark proxy URL (https://APP_ID:TOKEN@mum.egress.fixedmark.com:443) and the two IPs of your pair. Both are issued at launch. Join early access to get them.
  • Access to the partner's or database's allowlist, or a contact who can add two IPv4 addresses for you.

Steps

  1. 1
    Deploy a relay on a platform that supports proxiesUse the Node.js relay below on Railway, Render, Fly.io, or Cloud Run. Set FIXEDMARK_PROXY_URL and a random RELAY_SECRET there.
  2. 2
    Store the relay URL and secret in the WorkerRun npx wrangler secret put RELAY_SECRET. Set RELAY_URL under [vars] in wrangler.toml, or under vars in wrangler.jsonc.
  3. 3
    Call the relay from the WorkerReplace direct calls to the partner with calls to the relay. The partner sees only your Fixedmark pair.
  4. 4
    Lock down the relayAllow only the paths you need, and add a Fixedmark destination allowlist so the token can reach only the partner's host.
// The Worker cannot set a proxy on fetch, so it calls a relay you run
// on a platform that can. The relay holds the Fixedmark proxy URL.
export default {
  async fetch(request, env) {
    const res = await fetch(`${env.RELAY_URL}/v1/orders`, {
      headers: { authorization: `Bearer ${env.RELAY_SECRET}` },
    });
    return new Response(res.body, { status: res.status });
  },
};

The relay adds a second hop, so put it and the Fixedmark region close to the partner API, not close to your users.

Verify the egress IP on Workers

Check the IP before you send it to a partner. The IP that matters is the relay's. Run curl from the relay's shell, or add a temporary path to the relay that returns the proxied IP. The endpoint https://fixedmark.com/api/ip returns the caller's IP as plain text, and the What's my IP tool shows the same thing in a browser.

The proxied call should print one of your two Fixedmark IPs every time. The direct call should print a different address. If both print the same platform IP, the client is not using the proxy.

# From the relay's shell: the relay's egress through Fixedmark.
curl -sS --proxy "$FIXEDMARK_PROXY_URL" https://fixedmark.com/api/ip

# From anywhere: the IP a Worker uses without the relay.
# Deploy a Worker that returns (await fetch("https://fixedmark.com/api/ip")).text()
# and compare. It is a Cloudflare address and will not match your pair.

Databases from Workers

Workers reach databases over connect() TCP sockets or through Hyperdrive. Neither path can go through Fixedmark at launch. For an IP-restricted database, run the queries in the relay service, which can use SOCKS5 or bm tunnel. See Postgres and MySQL allowlists.

Common errors and fixes

The relay returns 401

The Worker's RELAY_SECRET does not match the relay's. Set the same value in both places, then redeploy the Worker.

The relay returns 502

The relay could not reach the partner through the proxy. Run the curl check from the relay to see whether the proxy or the partner refused the connection.

407 Proxy Authentication Required

The proxy did not get valid credentials. Check that the env var holds the full URL with APP_ID:TOKEN@, with no quotes or trailing newline. If the token contains @, :, or /, URL-encode it. Some clients drop credentials from the URL: pass them separately (Deno's basicAuth, axios proxy.auth) or switch to undici's ProxyAgent, which reads them from the URL.

TLS errors to the proxy: wrong version number, EPROTO, Proxy CONNECT aborted, or unable to connect to proxy

The client does not support an https:// proxy URL and is speaking plain HTTP to port 443. Upgrade it: curl 7.52+, urllib3 1.26+ (requests), httpx 0.26+, undici ProxyAgent, Go 1.10+. In Ruby, use Typhoeus: Net::HTTP and Faraday's default adapter cannot tunnel HTTPS through a TLS proxy. For older axios releases, set proxy: false and pass https-proxy-agent as httpsAgent. Java's built-in HttpClient cannot speak TLS to a proxy at all. If you cannot upgrade, use the SOCKS5 URL.

ETIMEDOUT or ECONNRESET to the partner, or a 403 from the partner

The proxy connected, but the destination dropped you. Usually only one IP of the pair is on the allowlist, or the partner has not applied the change yet. Add both IPs. If a destination allowlist is set on your Fixedmark token, check the host and port are on it.

The IP check prints the platform's IP, not a Fixedmark IP

The request went direct. Node's built-in fetch ignores HTTPS_PROXY unless NODE_USE_ENV_PROXY=1 is set (Node 22.21+ and 24+). Many SDKs ignore proxy env vars too. Pass the proxy to the client explicitly, as in the snippets above.

429 or 407 with an X-Proxy-Error: quota_exceeded header

Planned behavior when you pass your plan's soft limit. Check usage in the dashboard or raise the plan.

Database driver has no proxy option

node-postgres, mysql2, psycopg, and most ORMs cannot use an HTTP proxy. Use a SOCKS5-capable driver with FIXEDMARK_SOCKS_URL, or run bm tunnel where the platform allows a second process.

Gotchas on Workers

We do not support Workers directly at launch. If Cloudflare adds a proxy option to fetch, we will document it here.

  • connect() cannot reach Cloudflare IP ranges or port 25, so a relay behind Cloudflare is reached with fetch, not sockets.
  • Keep the relay's paths fixed. A relay that forwards any URL is an open proxy on your Fixedmark IPs.

Frequently asked questions

Can Cloudflare Workers use an HTTP proxy?

No. The Workers fetch API has no option to set a proxy, agent, or dispatcher. Outbound requests always leave from Cloudflare's network.

How do I get a static outbound IP for a Cloudflare Worker?

Call a small relay service that runs on a platform supporting proxies, and have the relay use a static IP proxy. On Enterprise, ask Cloudflare whether Dedicated CDN Egress IPs or Gateway egress IPs cover your Worker's traffic.

Can a Worker use a SOCKS5 proxy with connect()?

In principle, a Worker can do a SOCKS5 handshake on a plain socket and then call startTls. You would write HTTP by hand and send proxy credentials in clear text. Fixedmark does not support this path at launch.

Fix your egress IP.

Fixedmark is in early access. Join the list to get a dedicated IP pair for Cloudflare Workers when your region opens.