Zum Inhalt springen

Supabase 42501 permission denied: ein Grant, nicht RLS

Supabase

Als Markdown anzeigenIn Claude öffnenIn ChatGPT öffnenIn Perplexity öffnen

Die Frage wird ebenfalls kopiert. Falls der Chat leer öffnet, fügen Sie sie ein.

Kurz gesagt

42501 permission denied for table … heißt: Die Rolle hat keinen Grant auf die Tabelle, Postgres stoppt die Anfrage also, bevor eine RLS-Policy läuft. Ab dem 30. Oktober 2026 vergibt Supabase neue Tabellen in public bei bestehenden Projekten nicht mehr automatisch, Tabellen, die danach entstehen, antworten also mit 42501, bis Sie sie freigeben. Die Lösung sind drei Anweisungen zusammen: ein Grant für die Operationen, die die Rolle braucht, enable row level security und eine Policy. Nur zu vergeben, ohne RLS, öffnet die Tabelle für alle.

Ich habe einen kostenlosen Supabase-Sicherheitscheck gebaut, der die Grants jeder exponierten Tabelle liest, und 42501 ist der Fehler, den man bekommt, wenn die Grants in die andere Richtung falsch sind: zu wenige statt zu viele. Hier steht, was er bedeutet und was ich sah, als ich ihn nachgestellt habe.

Was bedeutet der Fehler 42501 in Supabase?

42501 ist der Postgres-Code für unzureichende Rechte. Postgres prüft zwei Ebenen, bevor ein Client eine Tabelle anfasst: Grants entscheiden, ob die Rolle die Operation überhaupt ausführen darf, und RLS-Policies entscheiden, welche Zeilen. Ein fehlender Grant scheitert zuerst, als Fehler. Eine Policy, die nichts trifft, scheitert leise, als leere Liste. Sehen Sie also 42501, schauen Sie auf die Grants, nicht auf Ihre Policies.

PostgREST, die Data API hinter supabase-js, reicht den Fehler mit einem Hinweis durch. Auf meinem lokalen Stack (Supabase CLI 2.109.1, Postgres 17.6, PostgREST 14.14) lieferte eine Anfrage mit dem publishable key an eine Tabelle ohne Grant für anon HTTP 401 und:

{
  "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"
}

Warum bekommen neue Tabellen nach dem 30. Oktober 2026 den Fehler 42501?

Bisher bekam eine neue Tabelle in public über Default-Privilegien select, insert, update und delete für anon, authenticated und service_role, war also in dem Moment über die Data API erreichbar, in dem sie angelegt wurde, geschützt oder nicht. Supabases Changelog entfernt diese Defaults: optional ab dem 28. April 2026, Standard für neue Projekte ab dem 30. Mai 2026 und auf alle bestehenden Projekte angewendet am 30. Oktober 2026. Bestehende Tabellen behalten ihre Grants.

Was die Umstellung sonst noch bricht und wie man das Projekt vorher prüft: Supabase-Änderung am 30. Oktober: Was bricht, wie prüfen.

Ich habe dieselbe Änderung mit den zwei Anweisungen alter default privileges … revoke aus dem Changelog auf mein lokales Projekt angewendet und dann eine neue Tabelle invoices angelegt:

Was eine neue Tabelle nach dem 30. Oktober 2026 antwortet. Lokales Supabase mit den neuen Default-Privilegien, je eine Anfrage. Publishable key, kein Grant: create table → kein Grant → 42501, HTTP 401; Secret key, kein Grant: create table → kein Grant → 42501, HTTP 403; Nach grant select und RLS an: grant select → RLS an → 0 Zeilen, HTTP 200.
Meine Nachstellung auf einem lokalen Supabase-Stack mit den Default-Privilegien aus dem Supabase-Changelog, 23. Oktober 2026.
Anfrage an die neue Tabelle Ergebnis
Publishable key, kein Grant HTTP 401, 42501, Hinweis GRANT SELECT ON public.invoices TO anon;
Secret key, kein Grant HTTP 403, 42501, Hinweis … TO service_role;
Publishable key, nach grant select und enable row level security HTTP 200, [], bis eine Policy Zeilen erlaubt

Zwei Dinge haben mich überrascht. Auch der secret key wird abgewiesen: service_role umgeht RLS, braucht aber trotzdem einen Grant, sodass eine Edge Function oder ein Server-Job, der in eine neue Tabelle schreibt, genauso kaputtgeht. Und das Revoke nimmt nur diese vier Operationen zurück: Die neue Tabelle kam weiterhin mit REFERENCES, TRIGGER und TRUNCATE für anon, authenticated und service_role. Auf TRUNCATE wirkt keine Policy.

Wie beheben Sie 42501, ohne die Tabelle zu öffnen?

Behandeln Sie Grant, RLS und Policy als eine Änderung in einer Migration, und geben Sie jeder Rolle nur, was sie braucht:

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);

Das revoke all räumt zuerst TRUNCATE, TRIGGER und REFERENCES weg, die mit der Tabelle kamen. Antworten Sie auf 42501 nicht mit grant all on all tables in schema public to anon: Das ist der alte Default zurück, für alle Tabellen auf einmal, und jede Tabelle ohne RLS ist für jeden mit Ihrem öffentlichen Key lesbar.

Wenn ein KI-Tool Ihre Tabellen anlegt, sagen Sie ihm, dass es Grants, RLS und Policies in derselben Migration ausgeben soll. Der Hinweis im Fehler ist so geschrieben, dass ein Agent den Grant selbst beheben kann, aber er nennt nur den Grant, nicht die RLS, die dazugehören sollte.

Wie sieht der Check das?

Vier seiner Regeln lesen die Grant-Ebene: “Standardrechte, die neue Objekte für die API öffnen” meldet Projekte, die neue Tabellen noch automatisch vergeben, “Ungenutzte Schreib-Grants für anonyme Besucher” findet Schreib-Grants für anon, die keine Policy nutzt, und “Unnötige Tabellenrechte für angemeldete Nutzer” findet TRUNCATE, TRIGGER und REFERENCES wie die oben. “Policies, die nie laufen: Der Rolle fehlt ein Grant” listet Tabellen auf, in denen eine Policy eine Rolle nennt, die für diesen Befehl keinen Grant hat; so sieht eine neue Tabelle nach dem 30. Oktober aus. Warum RLS nach dem Grant weiter zählt, steht in Supabase RLS testen, und wie Grants und Policies in einer ganzen App aussehen, in meiner Sicherheits-Checkliste für Lovable-Apps.

© 2026 Denys Zaichenko. Originalartikel: https://madsalt.tech/de/notes/supabase-42501-permission-denied/