Guide
Realtime says SUBSCRIBED but no events arrive
Updated
The most common cause is row level security quietly blocking the row for the subscribing role. SUBSCRIBED only means the WebSocket connected, not that the client may see the data.
Login, emails or payments broke in your live app? Our AI agent fixes it in your code, then tests your live app again.
Fixed in your code, then tested live. Check my app free
Why it happens
This applies to apps made with AI app builders that use Supabase as their backend and listen to database changes with Supabase Realtime (Postgres Changes).
Supabase Realtime enforces row level security the same way a normal query would, as the subscribing client's role. When the policy does not allow the row, no error is raised and the event simply does not arrive. A table that was never added to the supabase_realtime publication is also invisible to Realtime, no matter how the subscription is set up.
Possible causes
- Row level security blocks the changed row for the subscribing role, so the event is silently not delivered.
- The table is not in the supabase_realtime publication, so Realtime has no visibility into it at all.
- For UPDATE events, the policy generally has to allow both the old and the new row state; if the new state no longer passes the policy, the event can fail to deliver.
- The subscription's schema, table, event type or filter does not match the row that changed.
- A write made right after SUBSCRIBED can fall in a timing gap before the backend's replication listener is ready.
- A stale or duplicate channel from a component re-render keeps listening against an old parameter.
- Realtime is not enabled at the project level, or the project was paused and restarted and the replication slot needs to reconnect.
Official fix steps
- Check whether the table is listed in the supabase_realtime publication, and add it from Database then Publications in the dashboard if it is missing. (supabase.com)
- Select the changed row using the same credentials the client uses; empty data means the policy is blocking this row for this user. (supabase.com)
- Check that the table name matches exactly including case, the schema is correct, and the filter syntax is right. (supabase.com)
- Log the status callback and confirm the channel reports SUBSCRIBED rather than CHANNEL_ERROR, CLOSED or TIMED_OUT. (supabase.com)
- Clean up old channels when a component re-renders or a parameter changes, so only one subscription runs. (supabase.com)
- Check that Realtime is enabled under Project Settings then Realtime, and, if the project is under heavier load than usual, check the Concurrent Peak Connections quota. (supabase.com)
- Open Logs then Realtime in the dashboard and look for connection drops, replication errors and rate limiting. (supabase.com)
You can't see it yourself
You're signed in, your customers aren't. Realtime checks access as the role of the client that subscribes, so what arrives for your own signed-in session can differ from what arrives for a customer's role.
What to do next
App broke after you published it? Our AI agent fixes it in your code, then tests your live app again so you see the result yourself. The first check is free.
Fixed in your code, then tested live. Check my app free
Related: Supabase: new row violates row-level security policy on insert · Supabase "permission denied for table" (42501) fix · Users can see other users' data in my Lovable app
Sources
VibeFix's free check can show this on your live app: our AI agent tries your live app like a new user and shows you what breaks. On request, it reviews your code independently (VibeFix isn't part of any app builder), fixes it in your code and re-checks it live.
Last checked: 3 November 2026, against the sources listed above.
VibeFix is independent. Lovable, Bolt, Replit, Base44, v0 and Supabase are trademarks of their owners.
Want it fixed?
Our AI agent fixes it in your code and tests your live app again. See pricing.
It starts with a free check that confirms the problem on your live app, no account needed.