---
title: "Supabase 42501 permission denied: je to grant, nie RLS"
description: "Prečo Supabase vracia 42501 permission denied pre tabuľku, čo sa zmení 30. októbra 2026 a aký grant, RLS a politika to opravia. Reprodukované lokálne."
url: "https://madsalt.tech/sk/notes/supabase-42501-permission-denied/"
author: "Denys Zaichenko"
language: "sk"
published: 2026-10-26
---

# Supabase 42501 permission denied: je to grant, nie RLS

TL;DR

`42501 permission denied for table …` znamená, že rola nemá na tabuľku grant, takže Postgres zastaví požiadavku skôr, než sa spustí akákoľvek politika RLS. Od 30. októbra 2026 Supabase na existujúcich projektoch prestáva tabuľky v `public` automaticky sprístupňovať, takže tabuľky vytvorené neskôr odpovedajú 42501, kým im nedáte grant. Oprava sú tri príkazy dokopy: grant pre operácie, ktoré rola potrebuje, `enable row level security` a politika. Samotný grant bez RLS otvorí tabuľku všetkým.

Postavil som bezplatný [bezpečnostný checker pre Supabase](https://madsalt.tech/sk/tools/supabase-security-check/), ktorý číta granty na každej sprístupnenej tabuľke, a 42501 je chyba, na ktorú ľudia narazia, keď sú granty zle na opačnú stranu: príliš málo namiesto príliš veľa. Tu je, čo znamená a čo som videl, keď som ju reprodukoval.

## Čo znamená chyba 42501 v Supabase?

42501 je kód Postgresu pre nedostatočné oprávnenie. Postgres kontroluje dve vrstvy, než sa klient dotkne tabuľky: granty rozhodujú, či rola smie operáciu vôbec vykonať, a politiky RLS rozhodujú o riadkoch. Chýbajúci grant zlyhá prvý, ako chyba. Politika, ktorá nič nezodpovedá, zlyhá ticho, ako prázdny zoznam. Keď teda vidíte 42501, pozerajte sa na granty, nie na politiky.

PostgREST, Data API za `supabase-js`, chybu odovzdá ďalej s nápovedou. Na mojom lokálnom stacku (Supabase CLI 2.109.1, Postgres 17.6, PostgREST 14.14) vrátila požiadavka s publishable key na tabuľku bez grantu pre `anon` HTTP 401 a:

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

## Prečo nové tabuľky dostávajú 42501 po 30. októbri 2026?

Doteraz dostala nová tabuľka v `public` cez predvolené oprávnenia `select`, `insert`, `update` a `delete` pre `anon`, `authenticated` a `service_role`, takže bola dosiahnuteľná cez Data API hneď po vytvorení, chránená či nie. [Changelog](https://supabase.com/changelog/45329-breaking-change-tables-not-exposed-to-data-and-graphql-api-automatically) Supabase tieto predvolené nastavenia odstraňuje: voliteľne od 28. apríla 2026, ako predvolené pre nové projekty od 30. mája 2026 a na všetky existujúce projekty sa použije 30. októbra 2026. Existujúce tabuľky si granty ponechajú.

Čo ďalšie prepnutie pokazí a ako projekt skontrolovať vopred: [Supabase 30. októbra: zmena grantov a čo prestane fungovať](https://madsalt.tech/sk/blog/supabase-october-30-grant-change/).

Rovnakú zmenu som aplikoval na svoj lokálny projekt pomocou dvoch príkazov `alter default privileges … revoke` z changelogu a potom vytvoril novú tabuľku `invoices`:

![Čo odpovie nová tabuľka po 30. októbri 2026. Lokálny Supabase s novými predvolenými oprávneniami, vždy jedna požiadavka. Publishable key, bez grantu: create table → bez grantu → 42501, HTTP 401; Secret key, bez grantu: create table → bez grantu → 42501, HTTP 403; Po grant select a zapnutí RLS: grant select → RLS zapnuté → 0 riadkov, HTTP 200.](https://madsalt.tech/charts/sk/supabase-42501-permission-denied.svg)

*Moja reprodukcia na lokálnom Supabase s predvolenými oprávneniami z changelogu Supabase, 23. októbra 2026.*

| Požiadavka na novú tabuľku                                       | Výsledok                                                             |
| ---------------------------------------------------------------- | -------------------------------------------------------------------- |
| Publishable key, bez grantu                                      | HTTP 401, 42501, nápoveda `GRANT SELECT ON public.invoices TO anon;` |
| Secret key, bez grantu                                           | HTTP 403, 42501, nápoveda `… TO service_role;`                       |
| Publishable key, po `grant select` a `enable row level security` | HTTP 200, `[]`, kým politika nepovolí riadky                         |

Dve veci ma prekvapili. Secret key je odmietnutý tiež: `service_role` obchádza RLS, ale grant aj tak potrebuje, takže Edge Function alebo serverová úloha, ktorá zapisuje do novej tabuľky, sa pokazí rovnako. A revoke berie späť len tie štyri operácie: nová tabuľka aj tak prišla s `REFERENCES`, `TRIGGER` a `TRUNCATE` pre `anon`, `authenticated` a `service_role`. Na `TRUNCATE` sa žiadna politika nevzťahuje.

## Ako opraviť 42501, bez toho aby ste otvorili tabuľku?

Berte grant, RLS a politiku ako jednu zmenu v jednej migrácii a každej role dajte len to, čo potrebuje:

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

Úvodný `revoke all` zmaže `TRUNCATE`, `TRIGGER` a `REFERENCES`, ktoré prišli s tabuľkou. Na 42501 neodpovedajte príkazom `grant all on all tables in schema public to anon`: to je starý predvolený stav späť, pre všetky tabuľky naraz, a každá tabuľka bez RLS sa stane čitateľnou pre kohokoľvek s vaším verejným kľúčom.

Ak vaše tabuľky vytvára AI nástroj, povedzte mu, nech granty, RLS a politiky vydáva v rovnakej migrácii. Nápoveda v chybe je napísaná tak, aby agent mohol grant opraviť sám, ale menuje len grant, nie RLS, ktoré by k nemu malo prísť.

## Ako to vidí checker?

Štyri jeho pravidlá čítajú vrstvu grantov: „Predvolené oprávnenia, ktoré otvárajú nové objekty pre API“ označí projekty, ktoré stále automaticky sprístupňujú nové tabuľky, „Nepoužívané oprávnenia na zápis pre anonymných návštevníkov“ nájde zápisové granty pre `anon`, ktoré nepoužíva žiadna politika, a „Zbytočné oprávnenia na tabuľky pre prihlásených používateľov“ nájde `TRUNCATE`, `TRIGGER` a `REFERENCES` ako tie vyššie. „Politiky, ktoré nikdy nebežia: rola nemá grant“ vypíše tabuľky, kde politika uvádza rolu bez grantu na daný príkaz, a presne tak vyzerá nová tabuľka po 30. októbri. Prečo RLS záleží aj po grante, je v článku [ako testovať Supabase RLS](https://madsalt.tech/sk/blog/how-to-test-supabase-rls/) a ako vyzerajú granty a politiky naprieč celou aplikáciou, je v mojom [checkliste bezpečnosti aplikácie z Lovable](https://madsalt.tech/sk/blog/lovable-app-security-checklist/).
