Supabase Database Fix 5 min read

Supabase Not Working? Fix Auth, RLS, Connection & Edge Function Errors

Troubleshoot Supabase issues — auth session expired, Row Level Security blocking queries, database connection pool exhausted, Edge Functions cold start, and CORS errors when calling the API from a browser.

Supabase live status

Supabase — live status

Updated every 5 minutes · Full incident history →

Full status →

Common errors and fixes

RLS blocking all queries

If Row Level Security is enabled on a table but no policy exists, Supabase returns 0 rows (or a 403) for every query regardless of what data exists. Confirm and fix:

-- Check if RLS is enabled on a table
SELECT tablename, rowsecurity
FROM pg_tables
WHERE schemaname = 'public';

-- Temporarily disable to test (don't leave this in production!)
ALTER TABLE your_table DISABLE ROW LEVEL SECURITY;

-- Create a basic policy for authenticated users
CREATE POLICY "Users can read their own data"
  ON your_table
  FOR SELECT
  USING (auth.uid() = user_id);

-- Create a policy allowing all authenticated users to read
CREATE POLICY "Authenticated users can read"
  ON your_table
  FOR SELECT
  TO authenticated
  USING (true);
  • anon key: uses the anon role — most restrictive, subject to RLS policies you define.
  • service_role key: bypasses RLS entirely — use only server-side, never expose to the browser.
  • Re-enable RLS after testing: ALTER TABLE your_table ENABLE ROW LEVEL SECURITY;

Auth session issues

JWT tokens expire after 1 hour by default. Configure the client to auto-refresh and persist the session:

import { createClient } from '@supabase/supabase-js';

const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
  {
    auth: {
      autoRefreshToken: true,    // refresh before expiry
      persistSession: true,      // store in localStorage
      detectSessionInUrl: true,  // handle OAuth callbacks
    },
  }
);

// Check current session
const { data: { session }, error } = await supabase.auth.getSession();
if (!session) {
  // User not signed in
  await supabase.auth.signInWithOAuth({ provider: 'github' });
}

// Listen for auth changes
supabase.auth.onAuthStateChange((event, session) => {
  console.log(event, session); // SIGNED_IN, SIGNED_OUT, TOKEN_REFRESHED
});
  • Server-side rendering: ensure the session cookie is being set correctly — use @supabase/ssr for Next.js / SvelteKit server-side auth.
  • Verify user exists: check auth.users table in the Supabase Dashboard to confirm the account was created.

Database connection pool exhausted

Free tier allows 15 direct connections. For serverless environments (Vercel, Netlify, Cloudflare Workers), always use the pooled connection:

# Direct connection (port 5432) — max 15 on free tier
postgresql://postgres:[password]@db.[ref].supabase.co:5432/postgres

# Pooled connection via PgBouncer (port 6543) — use this for serverless
postgresql://postgres.[ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres

For Prisma, add connection limits to avoid saturating the pool:

# .env
DATABASE_URL="postgresql://[email protected]:6543/postgres?pgbouncer=true&connection_limit=1"
DIRECT_URL="postgresql://...@db.[ref].supabase.co:5432/postgres"
// schema.prisma
datasource db {
  provider  = "postgresql"
  url       = env("DATABASE_URL")
  directUrl = env("DIRECT_URL")  // for migrations
}
  • Transaction mode (port 6543): each query gets a connection from the pool and releases it immediately — ideal for serverless.
  • Session mode (port 5432): connection is held for the entire session — use for long-running processes only.

CORS errors on API calls

Supabase handles CORS for its REST API automatically. If you're getting CORS errors, the issue is usually in your setup:

Common mistakes: calling a localhost Supabase URL in production, or proxying through your own API without setting the correct headers. Never expose the service_role key to the browser.

For custom Edge Functions, add CORS headers manually:

// supabase/functions/my-function/index.ts
const corsHeaders = {
  'Access-Control-Allow-Origin': '*',
  'Access-Control-Allow-Headers': 'authorization, x-client-info, apikey, content-type',
};

Deno.serve(async (req) => {
  if (req.method === 'OPTIONS') {
    return new Response('ok', { headers: corsHeaders });
  }
  // ... your function logic
  return new Response(JSON.stringify(data), {
    headers: { ...corsHeaders, 'Content-Type': 'application/json' },
  });
});
  • Always handle OPTIONS preflight: browsers send a preflight OPTIONS request before any cross-origin POST — return 200 with CORS headers.
  • Restrict origin in production: replace '*' with your actual domain for tighter security.

Edge Functions — deploy and debug

Cold start can take 1–3 seconds for infrequently called functions. Use the Supabase CLI to deploy and tail logs:

# Install Supabase CLI
npm install -g supabase

# Login
supabase login

# Test locally (starts a local Supabase stack)
supabase start
supabase functions serve my-function --env-file .env.local

# Deploy to production
supabase functions deploy my-function --project-ref your-project-ref

# View logs
supabase functions logs my-function --project-ref your-project-ref
  • Environment variables: set in Dashboard → Edge Functions → Secrets. Access with Deno.env.get('MY_VAR').
  • Cold start latency: 1–3s is normal for infrequently-called functions — warm up with a periodic ping if latency matters.
  • Check logs first: Dashboard → Edge Functions → Logs shows runtime errors, uncaught exceptions, and invocation details.
🔔

Know when Supabase has an outage

Free email alerts. Star Supabase on Prismix — no credit card needed.

FAQ

Supabase vs Firebase — which is more reliable?

Both are managed BaaS platforms. Supabase is Postgres-based (open source, self-hostable). Firebase uses Firestore (NoSQL, Google infrastructure). For reliability comparison, check prismix.dev/service/supabase. Supabase had some growing pains in 2022–2023 but has stabilized significantly.

Supabase free tier limits

Free tier: 500MB database, 1GB storage, 2GB bandwidth, 50MB Edge Function memory, 500K Edge Function invocations/month. Projects pause after 1 week of inactivity (can be resumed manually). No credit card required for free tier.

Supabase AI / pgvector for embeddings

Supabase supports the pgvector extension for storing and querying embeddings. Enable it: CREATE EXTENSION vector; Then create a table: CREATE TABLE documents (id bigint primary key, content text, embedding vector(1536)); Use with OpenAI embeddings or any 1536-dim model for semantic search.

Monitor related services