supabase-js icon indicating copy to clipboard operation
supabase-js copied to clipboard

WebSocket connection failed on subscribing to realtime channel

Open skulltech opened this issue 2 years ago • 28 comments

Bug report

Describe the bug

I'm trying to use Supabase's realtime updates locally, and I'm getting the following error

WebSocket connection to 'ws://localhost:54321/realtime/v1/websocket?apikey=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0&vsn=1.0.0' failed

To Reproduce

  1. Clone this repo https://github.com/skulltech/sample-realtime-app
  2. Run yarn install and supabase start, and then yarn dev to start the server.
  3. Go to http://localhost:3000 and check the console to see the above mentioned error.
  4. The webapp has some basic functionality for writing and reading to database to make sure that the other Supabase functionalities are working as expected.

Expected behavior

No errors while subscribing to the realtime channel.

Screenshots

Screenshot 2023-01-08 at 1 13 15 AM

System information

  • OS: macOS
  • Browser: Chrome
  • Version of supabase-js: 2.2.3
  • Version of Node.js: v19.4.0
  • Version of Supabase CLI: 1.29.2
  • Version of Docker desktop for Mac: 4.15.0

Additional context

The same code seems to be working on production Supabase at app.supabase.com.

The same code was working before I updated my whole stack, i.e. updated Supabase CLI as well as @supabase/supabase-js, moved to Postgres v15 locally (i.e. in config.toml), from v14 previously, and ran brew upgrade which included updating docker desktop.

skulltech avatar Jan 07 '23 19:01 skulltech

Same here

image

'use client'

import { createBrowserClient } from '@landlord-fusion/supabase-browser-client'
import { Suspense, useEffect, useState } from 'react'

export default function ClientComponent({ serverData }: { serverData: any }) {
  const supabase = createBrowserClient

  const [data, setData] = useState(serverData)

  useEffect(() => {
    setData(serverData)
  }, [serverData])

  useEffect(() => {
    const channel = supabase
      .channel('custom-insert-channel')
      .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'customers' }, (payload) => {
        console.log('Change received!', payload)
      })
      .subscribe()

    return () => {
      supabase.removeChannel(channel)
    }
  }, [serverData, supabase])

  return (
     <pre>{JSON.stringify({ data }, null, 2)}</pre>
  )
}

OS: macOS Browser: Chrome Version of supabase-js: 2.2.3 Version of Node.js: v16.18.1 Version of Supabase CLI: 1.29.3 Version of Docker desktop for Mac: 4.15.0 (93002)

atanaskanchev avatar Jan 08 '23 13:01 atanaskanchev

I'm experiencing the same issue when trying to connect to self-hosted supabase on running dockers (locally):

  • @supabase/[email protected]
  • supabase/realtime:v2.0.2
  • supabase/postgres:14.1.0.89
  • supabase/gotrue:v2.40.1
  • kong:2.8.1
  • postgrest/postgrest:v9.0.1.20220717
  • supabase/postgres-meta:v0.52.1

aerophobic avatar Jan 09 '23 18:01 aerophobic

Fixed in "@supabase/supabase-js": "2.4.0" @skulltech @aerophobic

atanaskanchev avatar Jan 13 '23 13:01 atanaskanchev

@atanaskanchev I am having the same issues and I am using "@supabase/supabase-js": "2.4.0".

burkongla avatar Jan 14 '23 15:01 burkongla

@atanaskanchev I am having the same issues and I am using "@supabase/supabase-js": "2.4.0".

It has started working for me after I've updated all supabase dependencies to their latest versions and cleaned all docker images/containers 🤷‍♂️

atanaskanchev avatar Jan 14 '23 16:01 atanaskanchev

@atanaskanchev thank you, based on your comment I decided to try to update the supabase CLI also. That did the trick!

So if anyone has further issues as I did, make sure to update the supabase CLI version also.

burkongla avatar Jan 14 '23 19:01 burkongla

Having the same issue, websocket connection fails on my self hosted supabase

adityadhawan22 avatar Jan 15 '23 07:01 adityadhawan22

@skulltech @adityadhawan22 have you had a chance to check if updating and restarting the local dev setup (if using the CLI) or the supabase/realtime container (if using self-hosted) fixes it?

soedirgo avatar Jan 16 '23 05:01 soedirgo

I continue to have this issue after running brew upgrade supabase followed by supabase stop and supabase start.

Testing with:

this.supabase.client
      .channel('table-db-changes')
      .on(
        'postgres_changes',
        {
          event: '*',
          schema: 'public',
          table: 'my_table',
        },
        (payload) => {
          console.log('payload', payload);
        }
      )
      .subscribe()

jziggas avatar Jun 27 '23 17:06 jziggas

I have the same Issue here.

swissonid avatar Aug 10 '23 12:08 swissonid

Similar issue here. It's somehow related to our custom domain. All other queries work with the custom domain expect for realtime connections. Reverting to the non-custom domain for realtime connections solved the connection problem, but we now have a new problem of not being able to use a custom domain for all our requests.

jeffreyflynn avatar Sep 19 '23 11:09 jeffreyflynn

Running into the same issue here.

shihfu avatar Sep 20 '23 19:09 shihfu

We were also able to reproduce this issue with a custom domain. The problem seemed to persist when we reverted to using a vanity domain instead. We can also confirm that reverting to the base, non-custom (or vanity) subdomain works. We're not sure about how that effects local though (as originally reported).

hu0p avatar Oct 13 '23 22:10 hu0p

Also experiencing this.

allang avatar Oct 17 '23 05:10 allang

Also have this issue:

supabase/postgres │ 15.1.0.117 │ - supabase/gotrue │ v2.99.0 │ - postgrest/postgrest │ v11.2.0 │ - supabase/realtime │ v2.10.1 │ - supabase/storage-api │ v0.40.4 │ - supabase/edge-runtime │ v1.20.2 │ - supabase/studio │ 20230921-d657f29 │ - supabase/postgres-meta │ v0.68.0 │ - supabase/logflare │ 1.4.0 │ - bitnami/pgbouncer │ 1.20.1-debian-11-r39 │ - darthsim/imgproxy │ v3.8.0 │ -

Error:

` WebSocket connection to 'ws://localhost:54321/realtime/v1/websocket?apikey={apiKey}&vsn=1.0.0: failed

` Code:

` const entriesChannel = supabase .channel('custom-all-channel') .on('postgres_changes', { event: '*', schema: 'public', table: 'entries' }, (payload) => { console.log('Change received!', payload); }) .subscribe();

`

dependencies:

"@supabase/auth-helpers-sveltekit": "^0.10.3", "@supabase/auth-ui-shared": "^0.1.8", "@supabase/auth-ui-svelte": "^0.2.7", "@supabase/supabase-js": "^2.38.1",

Supabase CLI: 1.106.1

JamieBShaw avatar Oct 19 '23 12:10 JamieBShaw

We had the same issue, but it seemed like re-generating the JWT secret (and therefore changing the API keys) solved the problem...

fbeutel avatar Oct 27 '23 15:10 fbeutel

@fbeutel how did you re-generate the JWT secret? Experiencing the same issue

nataliaperina avatar Nov 15 '23 07:11 nataliaperina

any updates here? I am getting the same issue when trying to connect to localhost. Have tried clearing all of my docker containers/images (with docker system prune), as well as resetting the local JWT token by setting in an environment variable, and runningsupabase stop & supabase start a number of times

nataliaperina avatar Nov 15 '23 19:11 nataliaperina

Having this issue as well! I am using the supabase cli (1.110.1) so i don't know how i can rotate the jwt secrets/api keys. i can see the option to change keys when it is the docker-compose version but not with the cli deployment. The config.toml has no options to input my own api keys/jwt secrets. It works sometimes so im thinking it is some sort of connection issue with the elixir in the realtime container that is spawned. when it works, the logs in that conatiner show that it connected to the db. When it doesn't work, the logs hang here:

11:01:58.192 [info] create table tenants
11:01:58.208 [info] create index tenants_external_id_index
11:01:58.226 [info] == Migrated 20210706140551 in 0.0s
11:01:58.405 [info] == Running 20220329161857 Realtime.Repo.Migrations.AddExtensionsTable.change/0 forward
11:01:58.406 [info] create table extensions
11:01:58.415 [info] create index extensions_tenant_external_id_type_index
11:01:58.418 [info] == Migrated 20220329161857 in 0.0s
11:01:58.426 [info] == Running 20220410212326 Realtime.Repo.Migrations.AddTenantMaxEps.up/0 forward
11:01:58.426 [info] alter table tenants
11:01:58.428 [info] == Migrated 20220410212326 in 0.0s
11:01:58.436 [info] == Running 20220506102948 Realtime.Repo.Migrations.RenamePollIntervalToPollIntervalMs.up/0 forward
11:01:58.480 [debug] QUERY OK source="extensions" db=0.7ms
SELECT e0."id", e0."type", e0."settings", e0."tenant_external_id", e0."inserted_at", e0."updated_at" FROM "extensions" AS e0 WHERE (e0."type" = $1) ["postgres_cdc_rls"]
11:01:58.480 [info] == Migrated 20220506102948 in 0.0s
11:01:58.490 [info] == Running 20220527210857 Realtime.Repo.Migrations.AddExternalIdUniqIndex.change/0 forward
11:01:58.491 [info] execute "alter table tenants add constraint uniq_external_id unique (external_id)"
11:01:58.498 [info] == Migrated 20220527210857 in 0.0s
11:01:58.501 [info] == Running 20220815211129 Realtime.Repo.Migrations.NewMaxEventsPerSecondDefault.change/0 forward
11:01:58.502 [info] alter table tenants
11:01:58.505 [info] == Migrated 20220815211129 in 0.0s
11:01:58.513 [info] == Running 20220815215024 Realtime.Repo.Migrations.SetCurrentMaxEventsPerSecond.change/0 forward
11:01:58.513 [info] execute "update tenants set max_events_per_second = 1000"
11:01:58.514 [info] == Migrated 20220815215024 in 0.0s
11:01:58.526 [info] == Running 20220818141501 Realtime.Repo.Migrations.ChangeLimitsDefaults.change/0 forward
11:01:58.527 [info] alter table tenants
11:01:58.530 [info] == Migrated 20220818141501 in 0.0s
11:01:58.540 [info] == Running 20221018173709 Realtime.Repo.Migrations.AddCdcDefault.up/0 forward
11:01:58.540 [info] alter table tenants
11:01:58.542 [info] == Migrated 20221018173709 in 0.0s
11:01:58.554 [info] == Running 20221102172703 Realtime.Repo.Migrations.RenamePgType.up/0 forward
11:01:58.554 [info] execute "update extensions set type = 'postgres_cdc_rls'"
11:01:58.555 [info] == Migrated 20221102172703 in 0.0s
11:01:58.562 [info] == Running 20221223010058 Realtime.Repo.Migrations.DropTenantsUniqExternalIdIndex.change/0 forward
11:01:58.562 [info] execute "ALTER TABLE IF EXISTS tenants DROP CONSTRAINT IF EXISTS uniq_external_id"
11:01:58.564 [info] == Migrated 20221223010058 in 0.0s
11:01:58.575 [info] == Running 20230110180046 Realtime.Repo.Migrations.AddLimitsFieldsToTenants.change/0 forward
11:01:58.575 [info] alter table tenants
11:01:58.579 [info] == Migrated 20230110180046 in 0.0s
11:02:00.147 [debug] QUERY OK db=2.4ms queue=170.4ms idle=0.0ms
begin []
11:02:00.179 [debug] QUERY OK source="tenants" db=0.6ms
SELECT t0."id", t0."name", t0."external_id", t0."jwt_secret", t0."postgres_cdc_default", t0."max_concurrent_users", t0."max_events_per_second", t0."max_bytes_per_second", t0."max_channels_per_client", t0."max_joins_per_second", t0."inserted_at", t0."updated_at" FROM "tenants" AS t0 WHERE (t0."external_id" = $1) ["realtime-dev"]
11:02:00.246 [debug] QUERY OK db=2.7ms
INSERT INTO "tenants" ("external_id","jwt_secret","max_bytes_per_second","max_channels_per_client","max_concurrent_users","max_events_per_second","max_joins_per_second","name","inserted_at","updated_at","id") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11) ["realtime-dev", "iNjicxc4+llvc9wovDvqymwfnj9teWMlyOIbJ8Fh6j2WNU8CIJ2ZgjR6MUIKqSmeDmvpsKLsZ9jgXJmQPpwL8w==", 100000, 100, 200, 100, 500, "realtime-dev", ~N[2023-11-16 11:02:00], ~N[2023-11-16 11:02:00], <<225, 192, 199, 96, 240, 115, 70, 1, 169, 199, 221, 199, 106, 185, 146, 82>>]
11:02:00.259 [debug] QUERY OK db=10.2ms
INSERT INTO "extensions" ("settings","tenant_external_id","type","inserted_at","updated_at","id") VALUES ($1,$2,$3,$4,$5,$6) [%{"db_host" => "AsqXnLl1QzQhVdHgRakhwOUGygfGJMQFydI5HihZBh8=", "db_name" => "sWBpZNdjggEPTQVlI52Zfw==", "db_password" => "sWBpZNdjggEPTQVlI52Zfw==", "db_port" => "+enMDFi1J/3IrrquHHwUmA==", "db_user" => "uxbEq/zz8DXVD53TOI1zmw==", "ip_version" => 4, "poll_interval_ms" => 100, "poll_max_changes" => 100, "poll_max_record_bytes" => 1048576, "publication" => "supabase_realtime", "region" => "us-east-1", "slot_name" => "supabase_realtime_replication_slot"}, "realtime-dev", "postgres_cdc_rls", ~N[2023-11-16 11:02:00], ~N[2023-11-16 11:02:00], <<17, 62, 60, 18, 127, 16, 69, 135, 159, 15, 42, 23, 194, 166, 87, 139>>]
11:02:00.260 [debug] QUERY OK db=1.1ms
commit []
11:02:04.803 [info] Elixir.Realtime.SignalHandler is being initialized...
11:02:04.804 [notice] SYN[[email protected]] Adding node to scope <users>
11:02:04.804 [notice] SYN[[email protected]] Creating tables for scope <users>
11:02:04.805 [notice] SYN[[email protected]|registry<users>] Discovering the cluster
11:02:04.805 [notice] SYN[[email protected]|pg<users>] Discovering the cluster
11:02:04.805 [notice] SYN[[email protected]] Adding node to scope <Elixir.RegionNodes>
11:02:04.805 [notice] SYN[[email protected]] Creating tables for scope <Elixir.RegionNodes>
11:02:04.806 [notice] SYN[[email protected]|registry<Elixir.RegionNodes>] Discovering the cluster
11:02:04.806 [notice] SYN[[email protected]|pg<Elixir.RegionNodes>] Discovering the cluster
11:02:04.830 [info] Running RealtimeWeb.Endpoint with cowboy 2.9.0 at :::4000 (http)
11:02:04.830 [info] Access RealtimeWeb.Endpoint at http://realtime.fly.dev
11:02:04.831 [notice] SYN[[email protected]] Adding node to scope <Elixir.PostgresCdcStream>
11:02:04.831 [notice] SYN[[email protected]] Creating tables for scope <Elixir.PostgresCdcStream>
11:02:04.832 [notice] SYN[[email protected]|registry<Elixir.PostgresCdcStream>] Discovering the cluster
11:02:04.832 [notice] SYN[[email protected]|pg<Elixir.PostgresCdcStream>] Discovering the cluster
11:02:04.834 [notice] SYN[[email protected]] Adding node to scope <Elixir.Extensions.PostgresCdcRls>
11:02:04.835 [notice] SYN[[email protected]] Creating tables for scope <Elixir.Extensions.PostgresCdcRls>
11:02:04.835 [notice] SYN[[email protected]|registry<Elixir.Extensions.PostgresCdcRls>] Discovering the cluster
11:02:04.835 [notice] SYN[[email protected]|pg<Elixir.Extensions.PostgresCdcRls>] Discovering the cluster
11:02:07.803 [debug] Tzdata polling for update.
11:02:08.053 [info] tzdata release in place is from a file last modified Fri, 22 Oct 2021 02:20:47 GMT. Release file on server was last modified Tue, 28 Mar 2023 20:25:39 GMT.
11:02:08.053 [debug] Tzdata downloading new data from https://data.iana.org/time-zones/tzdata-latest.tar.gz
11:02:08.270 [debug] Tzdata data downloaded. Release version 2023c.
11:02:09.352 [info] Tzdata has updated the release from 2021e to 2023c
11:02:09.353 [debug] Tzdata deleting ETS table for version 2021e
11:02:09.356 [debug] Tzdata deleting ETS table file for version 2021e

Supabase local is an awesome tool but realtime is really important for our app so we can't afford to have a flaky local deployment :(

Deelaw97 avatar Nov 16 '23 11:11 Deelaw97

@fbeutel how did you re-generate the JWT secret? Experiencing the same issue

We are on the hosted version of supabase, where you can reset the JWT token in the admin panel... I'm not sure how that works in the self-hosted version. image

fbeutel avatar Nov 16 '23 19:11 fbeutel

The more recent issues might be its own, separate error; I opened https://github.com/supabase/realtime/issues/746

ghost avatar Nov 20 '23 00:11 ghost

I am having the same issue.

JunsikChoi avatar Dec 06 '23 07:12 JunsikChoi

Was also experiencing the same issue and restarted supabase a dozen times. What finally fixed it was clearing out all the local/session storage and cookies from the browser.

DavidMelnychuk avatar Apr 21 '24 21:04 DavidMelnychuk

For anyone having the same issue, what @DavidMelnychuk mentioned seems to solve the problem. At least it did for me.

I am running 2 separate supabase local instances (each with its own ports and project_id. Every time I switch to a project (to work on development), I need to remove the cache, and cookies from the browser, as it uses the cookies from the last used supabase instance.

Hope it helps!

MounirYounes avatar May 05 '24 03:05 MounirYounes

The WebSocket is throwing in the same way for us and its killing remote data monitoring as we've had to go back to polling until this fixed.

  • We're using the actual Supabase site and not localhost
  • We've tried rotating the JWT keys
  • We've tried clearing cookies / session storage and entirely new browsers with the same result

EDIT: Turns out that the patch put in place for #219 of supabase-realtime was screwing this up. Removing the transport config override fixes this issue.

hash-bang avatar May 16 '24 03:05 hash-bang

Was also experiencing the same issue and restarted supabase a dozen times. What finally fixed it was clearing out all the local/session storage and cookies from the browser.

Thanks! This worked for me too.

psiddharthdesign avatar Jul 30 '24 12:07 psiddharthdesign

Got the same issue for some users locally.

With the same oauth provider and different accounts on the same tenant within the authenticating provider! I'll also say that it's not possible to access other endpoints only on those accounts. So for some accounts, every endpoint works, for some accounts, the same ones (storage, realtime) don't, but others (auth, db) do.

My hypothesis is that one user has a longer name. When you sign in with some oauth providers, the JWT encodes a large amount of data (>8kb (!)) which could be the culprit.

The JWT gets passed as an query parameter (it seems) when establishing a connection, returning a 400 bad request, even though the same endpoint is accessible with another logged in user (different JWT).

For example, I was able to solve some earlier issues by increasing the cookie limit size in config.toml. But problems returned.

Hypothesis needs testing!

JungeWerther avatar Sep 17 '24 16:09 JungeWerther

Got the same issue for some users locally.

With the same oauth provider and different accounts on the same tenant within the authenticating provider! I'll also say that it's not possible to access other endpoints only on those accounts. So for some accounts, every endpoint works, for some accounts, the same ones (storage, realtime) don't, but others (auth, db) do.

My hypothesis is that one user has a longer name. When you sign in with some oauth providers, the JWT encodes a large amount of data (>8kb (!)) which could be the culprit.

The JWT gets passed as an query parameter (it seems) when establishing a connection, returning a 400 bad request, even though the same endpoint is accessible with another logged in user (different JWT).

For example, I was able to solve some earlier issues by increasing the cookie limit size in config.toml. But problems returned.

Hypothesis needs testing!

edit: I see that OP is using anon token so maybe JWT size is not the issue.

JungeWerther avatar Sep 17 '24 16:09 JungeWerther