diff --git a/packages/client/src/StreamSfuClient.ts b/packages/client/src/StreamSfuClient.ts
index 0434cc6fce..d3d2b21f18 100644
--- a/packages/client/src/StreamSfuClient.ts
+++ b/packages/client/src/StreamSfuClient.ts
@@ -227,16 +227,23 @@ export class StreamSfuClient {
       },
     });
 
-    this.signalWs.addEventListener('close', this.handleWebSocketClose);
-
     this.signalReady = makeSafePromise(
       Promise.race<WebSocket>([
-        new Promise((resolve) => {
+        new Promise((resolve, reject) => {
           const onOpen = () => {
             this.signalWs.removeEventListener('open', onOpen);
             resolve(this.signalWs);
           };
+
           this.signalWs.addEventListener('open', onOpen);
+
+          this.signalWs.addEventListener('close', () => {
+            this.handleWebSocketClose();
+            // Normally, this shouldn't have any effect, because WS should never emit 'close'
+            // before emitting 'open'. However, strager things have happened, and we don't
+            // want to leave signalReady in pending state.
+            reject(new Error('SFU WS closed unexpectedly'));
+          });
         }),
 
         new Promise((resolve, reject) => {
diff --git a/packages/client/src/rtc/signal.ts b/packages/client/src/rtc/signal.ts
index 5d4e68e959..4803b0d73d 100644
--- a/packages/client/src/rtc/signal.ts
+++ b/packages/client/src/rtc/signal.ts
@@ -9,6 +9,7 @@ export const createWebSocketSignalChannel = (opts: {
 }) => {
   const { endpoint, onMessage, logTag } = opts;
   const logger = getLogger(['SfuClientWS', logTag]);
+  logger('debug', 'Creating signaling WS channel:', endpoint);
   const ws = new WebSocket(endpoint);
   ws.binaryType = 'arraybuffer'; // do we need this?