You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Run this query in Log Explorer to classify recent 401s:
select
cast(timestampas datetime) astimestamp,
req.pathnameas function_name,
case
when metadata.execution_idis not null then 'your_code_returned_401'
when metadata.execution_id is nulland (
new_auth.prefixis not nullorlegacy_payload.algorithm!='HS256'
) then 'incompatible_keys'
when metadata.execution_id is nulland (
(legacy_auth_data.invalidis not nullornew_auth.erroris not null)
orlegacy_payload.algorithm='HS256'
) then 'invalid_key'
when metadata.execution_id is nulland legacy_auth_data is nullandnew_auth.prefix is null then 'missing_auth_header'
end as cause
from
function_edge_logs
-- unnesting metadatacross join UNNEST(metadata) as metadata
cross join UNNEST(metadata.request) as req
cross join UNNEST(metadata.response) as res
-- unnesting auth detailsleft join UNNEST(req.sb) as sb
left join UNNEST(sb.apikey) as apikey
left join UNNEST(apikey.authorization) as new_auth
left join UNNEST(sb.jwt) as legacy_jwt
left join UNNEST(legacy_jwt.authorization) as legacy_auth_data
left join UNNEST(legacy_auth_data.payload) as legacy_payload
whereres.status_code=401order bytimestampdesclimit50;
Depending on the output, you can use this table to find the appropriate debugging section:
Your function ran, and somewhere in your code, its logic returned a 401.
Example:
returnnewResponse(JSON.stringify(data),{headers: { ...corsHeaders,'Content-Type': 'application/json'},status: 401,// <-- you set this})
How to fix:
Search your function code for 401. Look for explicit status codes on Response objects.
Trace the condition that triggered it. If you're interacting with a third-party API in your code, that service may be returning 401 that you're forwarding in the response object.
Add logging before the return so future occurrences leave a trace:
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.
The subsections below cover specific failure modes.
Fix (alternative): If you want to keep the built-in check, ensure you're sending a valid key. Use one of your legacy API keys with the Supabase client library when making your request.
The built-in check is enabled but your request has no Authorization header at all.
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:
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
This is a copy of a troubleshooting article on Supabase's docs site. It may be missing some details from the original. View the original article.
A 401 response from an Edge Function means either:
Quick triage
Check the response body returned by the request
Case 1:
"Invalid Token"or"Missing authorization header"{ "code": 401, "message": "Invalid Token or Protected Header formatting" }{ "code": 401, "message": "Missing authorization header" }Both of these messages come from the legacy auth verification check
Go to: Built-in JWT check failures
Case 2: Custom message or empty body
If the response body contains a message you coded, or nothing at all, then your function code did execute and returned a 401 itself.
Go to: Your function returned a 401
Case 3: Not sure
Run this query in Log Explorer to classify recent 401s:
Depending on the output, you can use this table to find the appropriate debugging section:
your_code_returned_401incompatible_keysinvalid_keymissing_auth_headerYour function returned a 401
Your function ran, and somewhere in your code, its logic returned a 401.
Example:
How to fix:
401. Look for explicit status codes onResponseobjects.See: Error handling in Edge Functions
Built-in JWT check failures
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.The subsections below cover specific failure modes.
Incompatible key format
Your project uses the new asymmetric keys for authentication. However, the legacy auth verification check only understands the legacy format.
Fix: Disable the built-in JWT check using one of the below methods and optionally handle auth in your function code
Invalid key
The built-in check is enabled and the key you sent doesn't match your project's keys.
Fix (recommended): Disable the built-in check using the steps in Incompatible key format.
Fix (alternative): If you want to keep the built-in check, ensure you're sending a valid key. Use one of your legacy API keys with the Supabase client library when making your request.
Missing authorization header
The built-in check is enabled but your request has no
Authorizationheader at all.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:
Alternatively, you can disable the built-in check entirely (see Incompatible key format).
Additional resources
Still stuck?
Beta Was this translation helpful? Give feedback.
All reactions