Troubleshooting
WebSocket frames not showing in Chrome DevTools
The app is clearly talking — messages arrive, the UI updates — but the Messages tab is empty, or it's missing exactly the frames you came to look at. There are seven causes, and they're easy to tell apart once you know what each one looks like.
01You opened DevTools after the connection
This is most of the cases. Chrome only records frames from the moment DevTools is open on that tab. A socket that connected during page load has already exchanged its handshake, its auth, and probably a burst of initial state — none of which is in the list, with nothing to indicate anything is missing.
How to tell: the connection appears under the WS filter, but Messages is empty or starts mid-conversation. Fix: keep DevTools open and reload. If the bug only happens on the first connection of a cold session, that's the one case reloading can't recover.
02The connection isn't on WebSocket yet
Socket.IO connects over HTTP long-polling first and upgrades to WebSocket afterwards. Before the upgrade completes, your frames are HTTP request bodies, not WebSocket frames, and the WS filter hides them completely.
How to tell: switch the Network filter to All and look for repeating requests to /socket.io/?EIO=4&transport=polling. If those are carrying your data, the upgrade hasn't happened — often because a proxy in front of the app strips the Upgrade header.
03The socket lives in an iframe
The Network panel shows the frames of the inspected target. An embedded widget, a payment provider, an analytics iframe or a chat window served from another origin runs in its own context, and its socket doesn't appear in the top frame's list.
How to tell: use the context dropdown at the top of the Console (it says top by default) and switch to the iframe, or right-click the iframe and inspect it separately.
04The socket lives in a worker
A WebSocket opened inside a Web Worker, a Shared Worker or a service worker belongs to that worker's own DevTools target. The page's Network tab will not show it.
How to tell: open chrome://inspect/#workers, or the Application → Service Workers panel, and inspect the worker directly. Each gets its own Network tab.
05The frames are there, you just don't recognise them
Protocol framing makes your own messages look like someone else's. Socket.IO events arrive as 42["event",{…}], SignalR terminates messages with a 0x1e record separator that renders as nothing visible, and MQTT-over-WebSocket is binary from the first byte.
How to tell: the list is full of short numeric-looking rows and Binary Message (n bytes) entries. Nothing is missing — it's encoded. The socket.io field guide covers how to read that framing by hand.
06The filter is on
Worth ruling out early, because it costs five seconds. The Messages tab has its own filter box and a direction dropdown (All / Send / Receive), and both persist across page loads. The connection list also has a search box that's easy to leave text in.
How to tell: clear both filter boxes and set the dropdown back to All. If frames appear, that was it.
07Frames are being dropped from the buffer
DevTools caps how much frame data it keeps per connection. A high-frequency feed — market data, a game loop, a collaborative editor — will push older frames out, and a page that reloads repeatedly clears the list unless Preserve log is on.
How to tell: the oldest visible frame keeps moving forward in time while you watch. Fix: enable Preserve log, and narrow the reproduction so the interesting frames arrive close to when you start looking.
A quick way to rule out the browser
If you want to confirm the socket is doing anything at all, before deciding whose fault it is, paste this in the Console. It hooks the prototype, so it catches every socket created afterwards:
// logs every frame of every socket opened from now on
(() => {
const send = WebSocket.prototype.send;
WebSocket.prototype.send = function (d) { console.log('↑', d); return send.call(this, d); };
const add = WebSocket.prototype.addEventListener;
WebSocket.prototype.addEventListener = function (t, f, o) {
if (t !== 'message' || typeof f !== 'function') return add.call(this, t, f, o);
return add.call(this, t, (e) => { console.log('↓', e.data); return f.call(this, e); }, o);
};
})();
Two caveats, and they're the reason this trick only gets you so far: it can't see sockets that already exist, and libraries that assign socket.onmessage directly bypass the addEventListener hook entirely. To catch a socket.io connection from the handshake you need the patch installed before the page's own scripts run — which a console snippet, by definition, can't do.
Or install the hook before the page loads
Wirepeek is a free Chrome DevTools panel that does exactly that: it patches WebSocket.prototype — send, the onmessage setter and addEventListener — in the page's main world at document_start, so it captures from the handshake onward, survives reloads, and picks up iframe sockets too. Then it decodes what it captured: socket.io/engine.io framing, nested JSON, gzip, MessagePack, CBOR and more. Read-only, opt-in per tab, and nothing leaves your machine.