You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cloudflare Pages Worker调用Supabase API时DFW节点报1016错误求助

Cloudflare Pages边缘运行时调用Supabase出现1016 DNS错误(仅DFW节点)

环境配置

// src/lib/supabase.ts
import { createClient } from "@supabase/supabase-js";

export const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,      // https://[ref].supabase.co
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
  {
    global: { headers: { 'x-application-name': 'my-app' } }
  }
);
// src/app/blog/[slug]/page.tsx
export const runtime = "edge";

const getPost = cache(async (slug: string) => {
  const { data, error } = await supabase
    .from('BlogPost')
    .select('*')
    .eq('slug', slug)
    .single();

  if (error) {
    console.error('Fetch error:', error.message); // logs "error code: 1016"
    throw error;
  }
  return data;
});

错误日志

{
  "colo": "DFW",
  "logs": [{
    "message": ["Fetch error:", "error code: 1016"],
    "level": "error"
  }]
}

现象

  • BOM(孟买)边缘节点:✅ Supabase查询成功
  • DFW(达拉斯)边缘节点:❌ 所有查询、所有表均返回error code: 1016

已排除的可能原因

  • Supabase网络限制:已禁用,允许所有IP
  • Supabase网络封禁:无
  • API密钥:正确,在孟买节点可正常使用
  • RLS策略:非问题所在(包括公共表在内的所有表均失败)
  • Cloudflare智能部署:已启用,Worker仍在DFW执行

推测

my-site.com和supabase.co均为Cloudflare代理域名。当DFW节点的Worker调用fetch("https://[ref].supabase.co/rest/v1/...")时,Cloudflare将其作为Orange-to-Orange(O2O)请求路由。DFW边缘解析器在该O2O场景下无法解析Supabase源主机名,在建立TCP连接前返回1016错误。孟买节点正常可能因为其地理位置接近Supabase项目区域ap-south-1,使用了不同的内部路由路径。

问题

是否可以强制Cloudflare Pages Worker的fetch()调用绕过O2O路由,使用标准公共DNS解析?我了解Worker的fetch()有cf选项:

fetch(url, {
  // @ts-ignore
  cf: { /* ??? */ }
})

是否存在特定的cf选项可强制使用外部DNS解析而非Cloudflare内部O2O路径?或者有其他方法让Worker的出站请求独立于Cloudflare内部路由解析主机名?


解决方案

1. 强制使用公共DNS解析

通过自定义Supabase客户端的fetch方法,在cf参数中设置dns: "public",让边缘节点跳过内部O2O路由的DNS解析逻辑,直接使用公共DNS:

// src/lib/supabase.ts
import { createClient } from "@supabase/supabase-js";

// 自定义fetch,注入公共DNS解析配置
const customFetch = (url: RequestInfo, init?: RequestInit) => {
  return fetch(url, {
    ...init,
    cf: {
      ...init?.cf,
      dns: "public" // 强制使用公共DNS解析
    }
  });
};

export const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
  {
    global: { 
      headers: { 'x-application-name': 'my-app' },
      fetch: customFetch // 替换为自定义fetch
    }
  }
);

2. 直接指定Supabase实例IP(备选方案)

如果公共DNS解析仍有问题,可以通过resolveOverride直接指定Supabase实例的IP地址(可通过nslookup [ref].supabase.co获取对应IP):

// src/lib/supabase.ts
import { createClient } from "@supabase/supabase-js";

const supabaseHost = new URL(process.env.NEXT_PUBLIC_SUPABASE_URL!).hostname;
// 替换为你的Supabase实例实际IP
const SUPABASE_IP = "1.2.3.4";

const customFetch = (url: RequestInfo, init?: RequestInit) => {
  const targetUrl = typeof url === 'string' ? new URL(url) : new URL(url.url);
  const cfOptions = targetUrl.hostname === supabaseHost 
    ? { resolveOverride: SUPABASE_IP } 
    : {};

  return fetch(url, {
    ...init,
    cf: {
      ...init?.cf,
      ...cfOptions
    }
  });
};

export const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
  {
    global: { 
      headers: { 'x-application-name': 'my-app' },
      fetch: customFetch
    }
  }
);

原理说明

  • dns: "public":强制Cloudflare边缘节点使用公共DNS服务器解析目标域名,绕开内部O2O路由的解析逻辑,避免DFW节点的内部解析故障。
  • resolveOverride:直接指定目标域名的IP,完全跳过DNS解析步骤,从根源上解决1016 DNS错误问题。

内容的提问来源于stack exchange,提问作者Gods Neo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 15:47:27