---
title: "Supabase 42501 permission denied: en tilgang, ikke RLS"
description: "Hvorfor Supabase svarer 42501 permission denied, hva som endres 30. oktober 2026, og tilgangen, RLS og policyen som fikser det, reprodusert lokalt."
url: "https://madsalt.tech/no/notes/supabase-42501-permission-denied/"
author: "Denys Zaichenko"
language: "no"
published: 2026-10-26
---

# Supabase 42501 permission denied: en tilgang, ikke RLS

TL;DR

`42501 permission denied for table …` betyr at rollen ikke har noen tilgang (grant) på tabellen, så Postgres stopper forespørselen før noen RLS-policy kjører. Fra 30. oktober 2026 slutter Supabase å gi nye tabeller i `public` tilgang automatisk i eksisterende prosjekter, så tabeller opprettet etter den datoen svarer 42501 til du gir dem tilgang. Løsningen er tre setninger sammen: en tilgang for operasjonene rollen trenger, `enable row level security` og en policy. Å gi tilgang alene, uten RLS, åpner tabellen for alle.

Jeg har bygget en gratis [Supabase-sikkerhetssjekk](https://madsalt.tech/no/tools/supabase-security-check/) som leser tilgangene på hver eksponerte tabell, og 42501 er feilen folk møter når tilgangene er feil i den andre retningen: for få i stedet for for mange. Her er hva den betyr og hva jeg så da jeg reproduserte den.

## Hva betyr feilen 42501 i Supabase?

42501 er Postgres-koden for utilstrekkelig rettighet. Postgres sjekker to lag før en klient rører en tabell: tilganger avgjør om rollen i det hele tatt kan kjøre operasjonen, og RLS-policyer avgjør hvilke rader. En manglende tilgang feiler først, som en feil. En policy som ikke treffer noe, feiler stille, som en tom liste. Så når du ser 42501, se på tilganger, ikke på policyene dine.

PostgREST, Data API-et bak `supabase-js`, sender feilen videre med et hint. På den lokale stacken min (Supabase CLI 2.109.1, Postgres 17.6, PostgREST 14.14) svarte en forespørsel med publishable key mot en tabell uten tilgang for `anon` med HTTP 401 og:

```json
{
  "code": "42501",
  "details": null,
  "hint": "Grant the required privileges to the current role with: GRANT SELECT ON public.orders TO anon;",
  "message": "permission denied for table orders"
}
```

## Hvorfor får nye tabeller 42501 etter 30. oktober 2026?

Til nå fikk en ny tabell i `public` `select`, `insert`, `update` og `delete` for `anon`, `authenticated` og `service_role` gjennom standardrettigheter, så den kunne nås over Data API-et i det øyeblikket den ble opprettet, beskyttet eller ikke. Supabases [changelog](https://supabase.com/changelog/45329-breaking-change-tables-not-exposed-to-data-and-graphql-api-automatically) fjerner disse standardene: valgfritt fra 28. april 2026, standard for nye prosjekter fra 30. mai 2026, og innført for alle eksisterende prosjekter 30. oktober 2026. Eksisterende tabeller beholder tilgangene sine.

Hva mer omleggingen knekker, og hvordan du sjekker prosjektet på forhånd: [Supabase 30. oktober: hva som knekker og hvordan sjekke](https://madsalt.tech/no/blog/supabase-october-30-grant-change/).

Jeg brukte den samme endringen på det lokale prosjektet mitt med de to `alter default privileges … revoke`-setningene fra changeloggen, og opprettet så en ny tabell `invoices`:

![Hva en ny tabell svarer etter 30. oktober 2026. Lokal Supabase med de nye standardrettighetene, én forespørsel hver. Publishable key, ingen tilgang: create table → ingen tilgang → 42501, HTTP 401; Secret key, ingen tilgang: create table → ingen tilgang → 42501, HTTP 403; Etter grant select og enable RLS: grant select → RLS på → 0 rader, HTTP 200.](https://madsalt.tech/charts/no/supabase-42501-permission-denied.svg)

*Reproduksjonen min på en lokal Supabase-stack med standardrettighetene fra Supabase-changeloggen, 23. oktober 2026.*

| Forespørsel mot den nye tabellen                                     | Resultat                                                         |
| -------------------------------------------------------------------- | ---------------------------------------------------------------- |
| Publishable key, ingen tilgang                                       | HTTP 401, 42501, hint `GRANT SELECT ON public.invoices TO anon;` |
| Secret key, ingen tilgang                                            | HTTP 403, 42501, hint `… TO service_role;`                       |
| Publishable key, etter `grant select` og `enable row level security` | HTTP 200, `[]` til en policy slipper inn rader                   |

To ting overrasket meg. Secret key nektes også: `service_role` omgår RLS, men trenger likevel en tilgang, så en Edge Function eller en serverjobb som skriver til en ny tabell går i stykker på samme måte. Og `revoke` tar bare tilbake de fire operasjonene: den nye tabellen kom fortsatt med `REFERENCES`, `TRIGGER` og `TRUNCATE` for `anon`, `authenticated` og `service_role`. Ingen policy gjelder for `TRUNCATE`.

## Hvordan fikser du 42501 uten å åpne tabellen?

Behandle tilgangen, RLS og policyen som én endring, i én migrasjon, og gi hver rolle bare det den trenger:

```sql
revoke all on table public.invoices from anon, authenticated;
grant select, insert, update on table public.invoices to authenticated;
grant select, insert, update, delete on table public.invoices to service_role;

alter table public.invoices enable row level security;

create policy "Owners read their invoices"
on public.invoices for select
to authenticated
using ((select auth.uid()) = user_id);
```

`revoke all` først fjerner `TRUNCATE`, `TRIGGER` og `REFERENCES` som fulgte med tabellen. Svar ikke på 42501 med `grant all on all tables in schema public to anon`: det er den gamle standarden tilbake, for alle tabeller på én gang, og hver tabell uten RLS blir lesbar for alle med den offentlige nøkkelen din.

Hvis et AI-verktøy oppretter tabellene dine, be det lage tilganger, RLS og policyer i samme migrasjon. Hintet i feilen er skrevet slik at en agent kan fikse tilgangen selv, men hintet nevner bare tilgangen, ikke RLS-en som bør følge med.

## Hvordan ser sjekken dette?

Fire av reglene leser tilgangslaget: "Standardrettigheter som åpner nye objekter for API-et" flagger prosjekter som fortsatt gir nye tabeller tilgang automatisk, "Ubrukte skriverettigheter for anonyme besøkende" finner skrivetilganger for `anon` som ingen policy bruker, og "Unødvendige tabellrettigheter for innloggede brukere" finner `TRUNCATE`, `TRIGGER` og `REFERENCES` som de over. "Policyer som aldri kjører: rollen mangler tilgang" lister tabeller der en policy navngir en rolle som ikke har tilgang til den kommandoen, og slik ser en ny tabell ut etter 30. oktober. Hvorfor RLS fortsatt betyr noe etter at tilgangen er gitt, står i [hvordan du tester Supabase RLS](https://madsalt.tech/no/blog/how-to-test-supabase-rls/), og hvordan tilganger og policyer ser ut i en hel app, står i [sikkerhetsjekklisten min for Lovable-apper](https://madsalt.tech/no/blog/lovable-app-security-checklist/).
