Edge Function 401 error response
Last edited: 8/12/2026
Edge Function 返回 401 响应意味着以下情况之一:
🌐 A 401 response from an Edge Function means either:
- 该功能未通过旧版身份验证检查
- 你的函数逻辑故意返回了 401 响应
快速分诊 #
🌐 Quick triage
检查请求返回的响应体
🌐 Check the response body returned by the request
情况 1:"Invalid Token" 或 "Missing authorization header"#
🌐 Case 1: "Invalid Token" or "Missing authorization header"
1{ "code": 401, "message": "Invalid Token or Protected Header formatting" }1{ "code": 401, "message": "Missing authorization header" }这两条消息都来自旧版身份验证检查
🌐 Both of these messages come from the legacy auth verification check
前往:内置 JWT 检查失败
🌐 Go to: Built-in JWT check failures
案例 2:自定义消息或空内容 #
🌐 Case 2: Custom message or empty body
如果响应体包含你编写的消息,或者根本没有内容,那么你的函数代码确实执行过,并且自己返回了 401。
🌐 If the response body contains a message you coded, or nothing at all, then your function code did execute and returned a 401 itself.
前往:你的函数返回了 401
🌐 Go to: Your function returned a 401
情况3:不确定 #
🌐 Case 3: Not sure
在 Log Explorer 中运行此查询以分类最近的 401 错误:
🌐 Run this query in Log Explorer to classify recent 401s:
1select2 cast(timestamp as datetime) as timestamp,3 req.pathname as function_name,4 case5 when metadata.execution_id is not null then 'your_code_returned_401'6 when metadata.execution_id is null7 and (8 new_auth.prefix is not null9 or legacy_payload.algorithm != 'HS256'10 ) then 'incompatible_keys'11 when metadata.execution_id is null12 and (13 (legacy_auth_data.invalid is not null or new_auth.error is not null)14 or legacy_payload.algorithm = 'HS256'15 ) then 'invalid_key'16 when metadata.execution_id is null17 and legacy_auth_data is null18 and new_auth.prefix is null then 'missing_auth_header'19 end as cause20from21 function_edge_logs22 -- unnesting metadata23 cross join UNNEST(metadata) as metadata24 cross join UNNEST(metadata.request) as req25 cross join UNNEST(metadata.response) as res26 -- unnesting auth details27 left join UNNEST(req.sb) as sb28 left join UNNEST(sb.apikey) as apikey29 left join UNNEST(apikey.authorization) as new_auth30 left join UNNEST(sb.jwt) as legacy_jwt31 left join UNNEST(legacy_jwt.authorization) as legacy_auth_data32 left join UNNEST(legacy_auth_data.payload) as legacy_payload33where res.status_code = 40134order by timestamp desc35limit 50;根据输出情况,你可以使用此表找到相应的调试部分:
🌐 Depending on the output, you can use this table to find the appropriate debugging section:
| 值 | 前往 |
|---|---|
your_code_returned_401 | 你的函数返回了 401 |
incompatible_keys | 不兼容的密钥格式 |
invalid_key | 无效的密钥 |
missing_auth_header | 缺少授权头 |
你的函数返回了 401 #
🌐 Your function returned a 401
你的函数运行了,但在你的代码某处,它的逻辑返回了一个 401。
🌐 Your function ran, and somewhere in your code, its logic returned a 401.
示例:
1return new Response(JSON.stringify(data), {2 headers: { ...corsHeaders, 'Content-Type': 'application/json' },3 status: 401, // <-- you set this4})如何修复:
- 在你的函数代码中搜索
401。查看Response对象上的明确状态码。 - 追踪触发它的条件。如果你的代码中在与第三方 API 交互,该服务可能返回 401 状态码,而你在响应对象中转发了它。
- 在返回之前添加日志,这样将来发生时可以留下记录:
1console.error('Returning 401 - reason:', reason)🌐 See: Error handling in Edge Functions
内置 JWT 检查失败 #
🌐 Built-in JWT check failures
Supabase Edge Functions 有一个老的认证验证检查,会在你的代码运行前执行。如果它失败了,你的函数根本不会执行,而且你会直接从平台收到带有 "Invalid JWT" 或 "Missing authorization header" 的 401 错误。
🌐 Supabase Edge Functions have a legacy auth verification check that runs before your code. When it fails, your function never executes, and you get a 401 with "Invalid JWT" or "Missing authorization header" directly from the platform.
Supabase现在建议关闭这个内置检查,并直接在你的函数代码中管理认证,这样你就可以更好地控制访问。详情见 保护 Edge 函数。
🌐 Supabase now recommends turning off this built-in check and managing authentication directly in your function code, giving you more control over access. See Securing Edge Functions.
下面的小节讲述了具体的故障模式。
🌐 The subsections below cover specific failure modes.
密钥格式不兼容 #
🌐 Incompatible key format
你的项目使用了new asymmetric keys进行认证。不过,legacy auth verification check只认旧的格式。
🌐 Your project uses the new asymmetric keys for authentication. However, the legacy auth verification check only understands the legacy format.
修复: 使用下面的方法之一禁用内置的 JWT 检查,并可选择在你的函数代码中处理认证
无效的密钥 #
🌐 Invalid key
内置检查已启用,你发送的密钥和你项目的密钥不匹配。
🌐 The built-in check is enabled and the key you sent doesn't match your project's keys.
修复(推荐): 按照 不兼容密钥格式 中的步骤禁用内置检查。
修复(可选方案): 如果你想保留内置检查,请确保你发送的是有效的密钥。在发出请求时,使用你的传统 API 密钥和Supabase 客户端库。
1const supabase = createClient('https://xyzcompany.supabase.co', 'anon-key-or-service_role-key')缺少授权头 #
🌐 Missing authorization header
内置检查已启用,但你的请求根本没有 Authorization 头。
🌐 The built-in check is enabled but your request has no Authorization header at all.
如果你使用的是 Supabase 客户端库,头信息会自动添加。如果你是从外部客户端(cURL、fetch 等)调用该函数,你需要自己提供它:
🌐 If you're using a Supabase client library, the header is added automatically. If you're calling the function from an external client (cURL, fetch, etc.), you need to supply it:
1curl -L -X POST 'https://PROJECT_REF.supabase.co/functions/v1/hello-world' \2 -H 'Authorization: Bearer YOUR_ANON_OR_SERVICE_ROLE_KEY' \3 --data '{"name":"Functions"}'或者,你可以完全禁用内置检查(参见 不兼容的密钥格式)。
🌐 Alternatively, you can disable the built-in check entirely (see Incompatible key format).
额外资源 #
🌐 Additional resources
还卡住吗? #
🌐 Still stuck?
- 查看 Discord、Supabase GitHub 讨论 和 Reddit 页面 上的类似报告,这些可以帮助调试
- 如果问题持续存在,并且你认为这是平台问题,请为你的项目提交支持工单