How to fix PGRST100: Relation does not exist in Supabase

SupabaseINTERMEDIATEHIGHUpdated Dec 29, 2025· 177 views

The PGRST100 error occurs when Supabase (PostgREST API) cannot find the table you're trying to access. This can happen when the table is in a different schema, has a case-sensitivity issue, doesn't exist yet, or when the PostgREST schema cache hasn't been refreshed.

Quick fix

Fixes PGRST100: Relation does not exist

SELECT table_name FROM information_schema.tables
WHERE table_schema = 'public'
ORDER BY table_name;
  1. Verify the table exists in your database
  2. Check table name spelling and case sensitivity
  3. Refresh PostgREST schema cache for new tables
  4. For tables in custom schemas, use schema qualification
supabase — error
SELECT table_name FROM information_schema.tables
WHERE table_schema = 'public'
ORDER BY table_name;
PGRST100: Relation does not exist

What this error means

PostgREST is the REST API layer that Supabase uses to expose your PostgreSQL database. The PGRST100 error indicates that PostgREST tried to access a relation (table) that doesn't exist or isn't accessible at the current schema level. This is distinct from the PostgreSQL 42P01 error, though they have similar root causes. PGRST-prefixed errors come from PostgREST's own query parsing and schema interpretation layer, while 42P01 comes directly from PostgreSQL. The most common cause is attempting to access a table that either: 1. Doesn't exist in your database 2. Exists in a non-public schema without proper schema qualification 3. Has never been created 4. Was recently created but the PostgREST schema cache hasn't been reloaded

Typical symptoms

  • API calls return PGRST100 error with message 'Relation does not exist'
  • Supabase client calls fail when selecting from a table
  • Error appears immediately after creating a new table
  • Some tables work fine but others return PGRST100
  • Table works in PostgreSQL CLI but not through Supabase REST API

Common causes

  1. The table doesn't exist in your PostgreSQL database yet
  2. The table exists but is in a schema other than 'public' and wasn't specified in the query
  3. The table name has case-sensitivity issues (defined with quotes making it case-sensitive)
  4. Table was just created but PostgREST schema cache hasn't refreshed
  5. Table spelling is incorrect or doesn't match the actual database table name
  6. The table was dropped or deleted from the database
  7. Custom schema is not exposed to the Supabase API

How to fix "PGRST100: Relation does not exist"

1Verify the table exists in your database

First, confirm the table actually exists in PostgreSQL:

1. Open Supabase Dashboard > SQL Editor
2. Run this query to list all tables:

sql
SELECT table_name FROM information_schema.tables
WHERE table_schema = 'public'
ORDER BY table_name;

3. Look for your table in the results. If it's not there, the table doesn't exist yet and you need to create it:

sql
CREATE TABLE your_table (
  id BIGINT PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
  name TEXT NOT NULL,
  created_at TIMESTAMP DEFAULT NOW()
);

4. After creating the table, enable Row Level Security (RLS) in the Supabase dashboard by clicking the table and toggling RLS on

5. Add a simple policy to allow SELECT:

sql
ALTER TABLE your_table ENABLE ROW LEVEL SECURITY;

CREATE POLICY "Allow public read" ON your_table
FOR SELECT USING (true);
2Check table name spelling and case sensitivity

Table names are case-sensitive if they were created with quotes. Verify spelling:

1. In Supabase Dashboard, go to the Table Editor
2. Look at your table name exactly as it appears (e.g., users, Users, my_table)
3. Use that exact name (with correct case) in your queries:

typescript
// If table is named 'users' (lowercase)
const { data, error } = await supabase
  .from('users')  // Must match exactly
  .select();

// If table is named 'Users' (capitalized)
const { data, error } = await supabase
  .from('Users')  // Must match exactly
  .select();

If your table was created with CREATE TABLE "MyTable", always use the exact casing in queries.

3Refresh PostgREST schema cache for new tables

If you just created a table and PostgREST hasn't detected it yet, the schema cache needs to refresh:

1. Option A - Quick Fix: Restart your Supabase instance by clicking the "Restart" button in Supabase Dashboard > Settings > API Settings

2. Option B - Wait for Auto-Refresh: PostgREST automatically refreshes its schema cache every 1-5 minutes, so waiting a moment might solve it

3. Option C - Re-deploy: In Supabase Cloud, the instance restarts automatically on schema changes, but if using self-hosted PostgREST, you'll need to restart it

bash
# If self-hosted, restart PostgREST
docker restart postgrest_container_name
# or
systemctl restart postgrest

After restarting, your new table should be accessible via the REST API.

4For tables in custom schemas, use schema qualification

If your table is in a schema other than 'public', you must specify the schema:

1. First, ensure the custom schema is exposed to the Supabase API:

sql
-- In Supabase SQL Editor, add the schema to exposed schemas
SELECT net.http_get('http://localhost:3000/api/schema')
-- Or manually verify PostgREST config includes your schema

2. In your Supabase client, use the .schema() method:

typescript
const { data, error } = await supabase
  .schema('my_custom_schema')  // Specify non-public schema
  .from('my_table')
  .select();

3. If you get a 42501 "permission denied" error after this, you need to grant permissions:

sql
GRANT USAGE ON SCHEMA my_custom_schema TO authenticated;
GRANT SELECT ON ALL TABLES IN SCHEMA my_custom_schema TO authenticated;
5Enable Row Level Security and set policies

Tables need RLS enabled and policies configured to be accessible via the REST API:

1. In Supabase Dashboard, go to Authentication > Policies
2. For each table, click and enable RLS
3. Add at least one policy to allow access:

sql
-- Allow authenticated users to read all rows
CREATE POLICY "Enable read access for authenticated users"
ON your_table FOR SELECT
TO authenticated
USING (true);

-- Allow authenticated users to insert
CREATE POLICY "Enable insert for authenticated users"
ON your_table FOR INSERT
TO authenticated
WITH CHECK (true);

-- Allow authenticated users to update their own data
CREATE POLICY "Enable update for users based on id"
ON your_table FOR UPDATE
TO authenticated
USING (auth.uid() = user_id);

Without RLS policies, even though the table exists, the REST API won't be able to access it.

6Check Supabase client initialization

Ensure your Supabase client is properly initialized with correct URL and API key:

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

const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL,  // Must be valid
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY  // Must be valid anon key
);

// Verify connection works
const { data: { tables } } = await supabase
  .from('information_schema.tables')
  .select('table_name')
  .eq('table_schema', 'public');

console.log('Available tables:', tables);

If the client isn't initialized with correct credentials, it might not be connecting to the right database at all.

Advanced notes

PostgREST vs PostgreSQL Errors: While PostgreSQL returns 42P01 for "relation does not exist", PostgREST returns PGRST100 when it encounters the same issue at the REST API layer. The underlying cause is usually the same, but PGRST100 indicates PostgREST is the component reporting the error.

Schema Cache Mechanics: PostgREST maintains an in-memory cache of your database schema (table names, columns, types, etc.). When you create a new table, PostgREST won't see it until the cache refreshes. In Supabase Cloud, this typically happens automatically within 1-5 minutes or on restart. Self-hosted PostgREST requires manual schema cache clearing.

RLS and REST API Access: A common gotcha is that even if a table exists and is spelled correctly, the REST API can't access it without proper RLS policies. This is a security feature—rows are hidden by default until you explicitly grant access via policies.

Debugging Tips:
1. Always check the Supabase SQL Editor first to verify the table exists
2. Use information_schema queries to check table existence programmatically
3. Look at PostgREST logs if self-hosted: they often show the exact table name it's looking for
4. When copying SQL from tutorials, be mindful of schema prefixes and case sensitivity

Frequently asked questions

What does "PGRST100: Relation does not exist" mean?
PostgREST is the REST API layer that Supabase uses to expose your PostgreSQL database. The PGRST100 error indicates that PostgREST tried to access a relation (table) that doesn't exist or isn't accessible at the current schema level. This is distinct from the PostgreSQL 42P01 error, though they have similar root causes.
How do I fix "PGRST100: Relation does not exist"?
The PGRST100 error occurs when Supabase (PostgREST API) cannot find the table you're trying to access. This can happen when the table is in a different schema, has a case-sensitivity issue, doesn't exist yet, or when the PostgREST schema cache hasn't been refreshed.
What causes "PGRST100: Relation does not exist"?
The table doesn't exist in your PostgreSQL database yet The table exists but is in a schema other than 'public' and wasn't specified in the query The table name has case-sensitivity issues (defined with quotes making it case-sensitive)
Is the "PGRST100: Relation does not exist" error serious?
Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.

Official resources & further reading