Supabase Edge Functions Static IP (Deno Proxy)
Supabase Edge Functions have no static outbound IP, and Supabase's own docs recommend an outbound proxy. The IPv4 add-on gives your database an inbound address, not your functions an outbound one. Edge Functions run on Deno, so you can pass a Fixedmark proxy to `fetch` with `Deno.createHttpClient` and allowlist a dedicated IP pair.
Why Supabase Edge Functions have no fixed IP
Edge Functions run in isolates distributed across Supabase's infrastructure, close to your users or your database. The outbound address depends on where the isolate runs, and Supabase does not publish a fixed egress list for functions.
Apps built with Lovable use Supabase Edge Functions for server-side calls, so they hit the same wall when a payment gateway, CRM, or customer API demands a fixed source IP.
Supabase's native options
Supabase has no static egress product for Edge Functions. Its troubleshooting guide says so and suggests routing calls through an outbound proxy you control. The dedicated IPv4 add-on is often mistaken for a fix. Per Supabase's docs, it costs about $4 per month on Pro and above and gives your database an IPv4 address for incoming connections. The docs state the outbound IP is not static.
That makes a proxy the only route today. Deno's fetch accepts a custom HTTP client with a proxy, which is the mechanism shown below. The Supabase Edge Runtime exposes Deno.createHttpClient from release 1.68.
Sources for Supabase Edge Functions pricing
Checked October 2026. Confirm current details on the vendor's site before you decide. Prices and limits change.
- Supabase docs: Why Edge Functions cannot provide static egress IPs
- Supabase docs: Dedicated IPv4 address
- Supabase Edge Runtime: Deno.createHttpClient support
- Deno API: Deno.createHttpClient
Set up a static IP on Supabase Edge Functions
You create one proxied client per function and pass it to the fetch calls that need the fixed IP.
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 Supabase project and the Supabase CLI, logged in and linked (
supabase link). - 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
- 1Store the proxy URL as a function secretRun
supabase secrets set FIXEDMARK_PROXY_URL=https://APP_ID:TOKEN@mum.egress.fixedmark.com:443, or add it under Edge Functions, Secrets in the dashboard. Secrets are available to every function throughDeno.env.getwithout a redeploy. - 2Create the proxied client at module scopeCall
Deno.createHttpClient({ proxy: { url, basicAuth } })once, outsideDeno.serve, so the isolate reuses it across requests. - 3Pass the client to fetchAdd
clientto thefetchoptions for the allowlisted calls. Calls to Supabase itself (database, storage, auth) stay direct. - 4Deploy, verify, and allowlist both IPsRun
supabase functions deploy partner-orders. Deploy the IP check function below once, invoke it, then give the partner both IPs from your Fixedmark pair.
// supabase/functions/partner-orders/index.ts
const proxy = new URL(Deno.env.get("FIXEDMARK_PROXY_URL")!);
// Create the client once per isolate, not per request.
const client = Deno.createHttpClient({
proxy: {
url: `${proxy.protocol}//${proxy.host}`,
basicAuth: {
username: decodeURIComponent(proxy.username),
password: decodeURIComponent(proxy.password),
},
},
});
Deno.serve(async () => {
const res = await fetch("https://api.partner.example/v1/orders", {
client,
headers: { authorization: `Bearer ${Deno.env.get("PARTNER_API_KEY")}` },
});
return new Response(await res.text(), { status: res.status });
});// Pass credentials as basicAuth instead of relying on URL userinfo.
const proxy = new URL(Deno.env.get("FIXEDMARK_PROXY_URL")!);
const client = Deno.createHttpClient({
proxy: {
url: `${proxy.protocol}//${proxy.host}`,
basicAuth: {
username: decodeURIComponent(proxy.username),
password: decodeURIComponent(proxy.password),
},
},
});
const res = await fetch("https://api.partner.example/v1/orders", { client });
console.log(res.status, await res.json());The snippet passes credentials as basicAuth rather than inside the proxy URL, which is the form Deno documents. We tested this code on Deno 2 against an https:// proxy. We are still confirming that the hosted Supabase Edge Runtime allows the proxy option on every release, so run the IP check before you send the IPs to a partner.
Verify the egress IP on Supabase
Check the IP before you send it to a partner. Deploy the check below as its own function and invoke it with supabase functions invoke egress-check or curl. It returns both the proxied IP and the function's own 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.
// supabase/functions/egress-check/index.ts
// Deploy, invoke once, then delete the function.
const proxy = new URL(Deno.env.get("FIXEDMARK_PROXY_URL")!);
const client = Deno.createHttpClient({
proxy: {
url: `${proxy.protocol}//${proxy.host}`,
basicAuth: {
username: decodeURIComponent(proxy.username),
password: decodeURIComponent(proxy.password),
},
},
});
Deno.serve(async () => {
const via = await fetch("https://fixedmark.com/api/ip", { client });
const direct = await fetch("https://fixedmark.com/api/ip");
return Response.json({
fixedmark: (await via.text()).trim(),
platform: (await direct.text()).trim(),
});
});# Needs curl 7.52 or later for an https:// proxy URL.
# Prints the IP the destination sees. Run it a few times:
# you should only ever see the two IPs of your pair.
curl -sS --proxy "$FIXEDMARK_PROXY_URL" https://fixedmark.com/api/ip
# Same check over SOCKS5, the path database drivers use.
curl -sS --proxy "$FIXEDMARK_SOCKS_URL" https://fixedmark.com/api/ip
# Without the proxy, for comparison. This is the platform's own IP.
curl -sS https://fixedmark.com/api/ipDatabases from Edge Functions
Your Supabase database does not need any of this. Functions reach it over Supabase's network and the client libraries.
For an external IP-restricted database, Deno's Postgres and MongoDB drivers have no SOCKS5 option, and Edge Functions cannot run bm tunnel. Call the external database through an HTTP API via the proxied client, or move that query into a small service on a platform that can run the tunnel. See Postgres and MySQL allowlists.
Common errors and fixes
Deno.createHttpClient is not a function
Older Supabase Edge Runtime versions did not expose it. Update the Supabase CLI for local serving. On hosted projects, tell us during early access so we can track the runtime version.
Deno.env.get returns undefined for the secret
Secret names are case sensitive. Run supabase secrets list to check it exists in the linked project. Local supabase functions serve reads supabase/functions/.env, not hosted secrets.
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 Supabase
Deno's proxy client applies to fetch only. WebSocket connections and raw TCP from Deno.connect do not go through it.
- Do not rely on
HTTPS_PROXYin Edge Functions. Pass the client explicitly so only allowlisted calls use the proxy. - Function regions and Fixedmark regions do not always match. Pick the Fixedmark region nearest the partner API if functions run in many places.
- Keep the secret out of the browser. Never read it from client-side code in a Lovable or Next.js app.
- Outbound ports 25 and 587 are blocked on Edge Functions, through the proxy or not.
Related guides
- Use caseAI agents and automationsGive n8n workflows, Lovable apps, and AI agent tool calls a fixed IP that allowlisted APIs accept.
- Use casePartner API allowlistingGive Salesforce, SOAP vendors, and payment gateways one dedicated IP pair to allowlist, wherever your code runs.
- IntegrationVercelFixed egress IPs for Vercel Functions without the $100 per project add-on.
- IntegrationNetlifyA fixed source IP for Netlify Functions without an Enterprise contract.
Frequently asked questions
Do Supabase Edge Functions have a static IP?
No. Supabase does not offer static egress IPs for Edge Functions and recommends routing outbound calls through a proxy. A static IP proxy gives those calls a fixed source address.
Does the Supabase IPv4 add-on give Edge Functions a static IP?
No. Per Supabase's docs, the IPv4 add-on gives your database an IPv4 address for incoming connections. It does not change the outbound IP of Edge Functions.
How do I set a proxy for fetch in a Supabase Edge Function?
Create a client with Deno.createHttpClient({ proxy: { url, basicAuth } }) and pass it as the client option to fetch. Store the proxy URL as a function secret and read it with Deno.env.get.
Does this work for Lovable apps?
Yes. Lovable's backend runs on Supabase Edge Functions, so the same secret and client code apply. Put the proxied fetch in the edge function, never in browser code.
Can Edge Functions connect to an external Postgres through the static IP?
Not directly at launch. Deno's database drivers have no SOCKS5 option and functions cannot run a tunnel process. Use an HTTP API or a small relay service on another platform.
Fix your egress IP.
Fixedmark is in early access. Join the list to get a dedicated IP pair for Supabase Edge Functions when your region opens.