This error occurs when there's a network or routing issue between your client and Supabase's edge gateway. The relay layer handles authentication, routing, and traffic management for Edge Functions.
The EdgeFunctionRelayError indicates a failure in the relay layer that sits between your client application and Supabase Edge Functions. This relay acts as an edge gateway that routes traffic, validates JWT tokens, applies authentication rules, and manages traffic routing to your deployed functions. When you invoke a Supabase Edge Function, the request passes through this relay infrastructure before reaching your function code. If the relay cannot successfully process or forward the request, it throws an EdgeFunctionRelayError. This is distinct from function execution errors (FunctionsHttpError) or unreachable function errors (FunctionsFetchError). The error is detected by checking response headers for 'x-relay-error' set to 'true', indicating the relay layer encountered a problem before your function could execute.
Import and check for the specific error type to get more context:
import { createClient, FunctionsRelayError } from '@supabase/supabase-js'
const supabase = createClient(url, key)
const { data, error } = await supabase.functions.invoke('my-function')
if (error instanceof FunctionsRelayError) {
console.log('Relay error:', error.message)
console.log('Error details:', error)
}Check your browser's network tab for the failed request and look for the 'x-relay-error' header.
Run the function locally to determine if the issue is with your function code or the relay infrastructure:
supabase functions serve my-function --debugThen invoke it locally:
const { data, error } = await supabase.functions.invoke('my-function', {
headers: { 'x-region': 'local' }
})If it works locally but fails in production, the issue is likely with the relay layer or network connectivity.
Ensure your client has a valid authentication session:
// Check current session
const { data: { session } } = await supabase.auth.getSession()
if (!session) {
console.log('No active session - authentication required')
}
// Refresh session if needed
const { data: { session: newSession }, error } = await supabase.auth.refreshSession()The relay validates JWT tokens before forwarding requests. Expired or invalid tokens will cause relay failures.
Ensure your Edge Function returns proper CORS headers:
// In your Edge Function (index.ts)
Deno.serve(async (req) => {
// Handle CORS preflight
if (req.method === 'OPTIONS') {
return new Response('ok', {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
}
})
}
// Your function logic here
const data = { message: 'Success' }
return new Response(JSON.stringify(data), {
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
}
})
})Navigate to your Supabase Dashboard to check for errors:
1. Go to Edge Functions → [Your Function] → Logs
2. Look for relay errors, boot errors, or timeout issues
3. Check the function's boot time and execution duration
4. Verify the function isn't hitting the 60-second execution limit
If no logs appear, the request never reached your function, confirming a relay-layer issue.
Ensure your function is properly deployed and you're using the correct invocation:
# Deploy with debug output
supabase functions deploy my-function --debug
# Verify function exists
supabase functions listCheck that your invocation uses the correct function name:
// Correct function name must match deployed function
const { data, error } = await supabase.functions.invoke('my-function', {
body: JSON.stringify({ param: 'value' })
})If the error is intermittent (affecting ~1% of invocations), it may be a temporary infrastructure issue:
1. Check Supabase status page for reported incidents
2. Monitor error frequency in your application logs
3. Implement retry logic with exponential backoff:
async function invokeWithRetry(functionName, payload, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const { data, error } = await supabase.functions.invoke(functionName, payload)
if (!error || !(error instanceof FunctionsRelayError)) {
return { data, error }
}
if (i < maxRetries - 1) {
await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000))
}
}
throw new Error('Max retries exceeded for relay error')
}Relay Error Types
The Supabase client library provides three distinct error types for Edge Functions:
- FunctionsRelayError: Network/routing issue between client and Supabase (this error)
- FunctionsHttpError: Function executed but returned an error response
- FunctionsFetchError: Function is not reachable or doesn't exist
Understanding the Relay Layer
The relay layer is Supabase's edge gateway infrastructure that:
- Routes requests to the appropriate Edge Function deployment
- Validates authentication headers and JWT tokens
- Applies rate limiting and traffic management rules
- Handles geographic routing to nearest edge nodes
- Enforces function execution timeouts (60 seconds)
Size Limits
Edge Functions have the following limits enforced at the relay layer:
- 10MB maximum source code size during deployment
- Request payload size limits (typically 6MB for POST/PUT bodies)
- Response size limits for streaming responses
Monitoring and Diagnostics
For production applications, implement comprehensive error monitoring:
const { data, error } = await supabase.functions.invoke('my-function')
if (error) {
// Log to error tracking service (Sentry, LogRocket, etc.)
errorTracker.captureException(error, {
extra: {
errorType: error.constructor.name,
functionName: 'my-function',
timestamp: new Date().toISOString()
}
})
}If relay errors persist after troubleshooting, open a support ticket via the Supabase Dashboard with:
- Function name and project reference
- Error frequency and timing patterns
- Browser network tab screenshots showing x-relay-error header
- Output from local testing with --debug flag
email_address_not_authorized: Email sending to this address is not authorized
Email address not authorized for sending in Supabase Auth
reauthentication_needed: Reauthentication required for security-sensitive actions
Reauthentication required for security-sensitive actions
no_authorization: No authorization header was provided
How to fix "no authorization header was provided" in Supabase
otp_expired: OTP has expired
How to fix 'otp_expired: OTP has expired' in Supabase
bad_oauth_state: OAuth state parameter is missing or invalid
How to fix 'bad_oauth_state: OAuth state parameter missing' in Supabase