본문으로 건너뛰기
cccskills
무료GitHub에 공개

debugging-websocket-issues

Use when seeing WebSocket errors like "Invalid frame header", "RSV1 must be clear", or "WS_ERR_UNEXPECTED_RSV_1" - covers multiple WebSocketServer conflicts, compression issues, and raw frame debugging techniques

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md5.1 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

Debugging WebSocket Issues

Overview

WebSocket "invalid frame header" errors often stem from raw HTTP being written to an upgraded socket, not actual frame corruption. The most common cause is multiple WebSocketServer instances conflicting on the same HTTP server.

When to Use

  • Error: Invalid WebSocket frame: RSV1 must be clear
  • Error: WS_ERR_UNEXPECTED_RSV_1
  • Error: Invalid frame header
  • WebSocket connects then immediately disconnects with code 1006
  • Server logs success but client receives garbage data

Quick Reference

SymptomLikely CauseFix
RSV1 must be clearMultiple WSS on same server OR compression mismatchUse noServer: true mode
Hex starts with 48545450Raw HTTP on WebSocket (0x48='H')Check for conflicting upgrade handlers
Code 1006, no reasonAbnormal closure, often server-side abortCheck abortHandshake calls
Works isolated, fails in appSomething else writing to socketAudit all upgrade listeners

The Multiple WebSocketServer Bug

Problem

When attaching multiple WebSocketServer instances to the same HTTP server using the server option:

// ❌ BAD - Both servers add upgrade listeners, causing conflicts
const wss1 = new WebSocketServer({ server, path: '/ws' });
const wss2 = new WebSocketServer({ server, path: '/ws/other' });

What happens:

  1. Client connects to /ws
  2. BOTH upgrade handlers fire (Node.js EventEmitter calls all listeners)
  3. wss1 matches path, handles upgrade successfully
  4. wss2 doesn't match, calls abortHandshake(socket, 400)
  5. Raw HTTP/1.1 400 Bad Request written to the now-WebSocket socket
  6. Client receives HTTP text as WebSocket frame data
  7. First byte 0x48 ('H') interpreted as: RSV1=1, opcode=8 → invalid frame

Solution

Use noServer: true and manually route upgrades:

// ✅ GOOD - Single upgrade handler routes to correct server
const wss1 = new WebSocketServer({ noServer: true, perMessageDeflate: false });
const wss2 = new WebSocketServer({ noServer: true, perMessageDeflate: false });

server.on('upgrade', (request, socket, head) => {
  const pathname = new URL(request.url || '', `http://${request.headers.host}`).pathname;

  if (pathname === '/ws') {
    wss1.handleUpgrade(request, socket, head, (ws) => {
      wss1.emit('connection', ws, request);
    });
  } else if (pathname === '/ws/other') {
    wss2.handleUpgrade(request, socket, head, (ws) => {
      wss2.emit('connection', ws, request);
    });
  } else {
    socket.destroy();
  }
});

Debugging Techniques

Raw Frame Inspection

Hook into the socket to see actual bytes received:

ws.on('open', () => {
  const socket = ws._socket;
  const originalPush = socket.push.bind(socket);

  socket.push = function (chunk, encoding) {
    if (chunk) {
      console.log('First 20 bytes (hex):', chunk.slice(0, 20).toString('hex'));
      const byte0 = chunk[0];
      console.log(`FIN: ${!!(byte0 & 0x80)}, RSV1: ${!!(byte0 & 0x40)}, Opcode: ${byte0 & 0x0f}`);

      // Check if it's actually HTTP text
      if (chunk.slice(0, 4).toString() === 'HTTP') {
        console.log('*** RECEIVED RAW HTTP ON WEBSOCKET ***');
      }
    }
    return originalPush(chunk, encoding);
  };
});

Key Hex Patterns

  • 81 = FIN + text frame (normal)
  • 82 = FIN + binary frame (normal)
  • 88 = FIN + close frame (normal)
  • 48545450 = "HTTP" - raw HTTP on WebSocket (bug!)
  • c1 or similar with bit 6 set = compressed frame (RSV1=1)

Common Mistakes

MistakeResultFix
Multiple WSS with server optionHTTP 400 written to socketUse noServer: true
perMessageDeflate: true (default in older ws)RSV1 set on framesExplicitly set perMessageDeflate: false
Not checking upgrade headersMiss compression negotiationLog sec-websocket-extensions header
Assuming RSV1 error = compressionCould be raw HTTPCheck if bytes decode as ASCII "HTTP"

Verification Checklist

After fixing, verify:

  • RSV1: false in frame inspection
  • Extensions header: NONE in upgrade response
  • No HTTP/1.1 in raw frame data
  • Messages received match sent payload size
  • Multiple broadcasts work (test interval sends)

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Use when you need Codex to coordinate multiple agents through Agent Relay for peer-to-peer messaging, lead/worker handoffs, or shared status tracking across sub-agents and terminals.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

AgentWorkforce/relay8872026년 10월 18일 업데이트

Use when testing web applications with visual verification - automates Chrome browser interactions, element selection, and screenshot capture for confirming UI functionality

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

AgentWorkforce/relay8872026년 10월 18일 업데이트

Use when coordinating multiple AI agents with Agent Relay's workflow engine and need to pick the right orchestration pattern - covers the 10 core patterns (fan-out, pipeline, hub-spoke, consensus, mesh, handoff, cascade, dag, debate, hierarchical) plus 14 specialized ones, with decision framework and accurate SDK/YAML examples.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

AgentWorkforce/relay8872026년 10월 18일 업데이트

Use when creating Agent Skills packages (SKILL.md format) for Codex CLI, GitHub Copilot, or Amp - provides the agentskills.io specification with frontmatter constraints, directory structure, and validation rules

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

AgentWorkforce/relay8872026년 10월 18일 업데이트

Use when creating or improving Claude Code agents. Expert guidance on agent file structure, frontmatter, persona definition, tool access, model selection, and validation against schema.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

AgentWorkforce/relay8872026년 10월 18일 업데이트

Use when creating or publishing Claude Code hooks - covers executable format, event types, JSON I/O, exit codes, security requirements, and PRPM package structure

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

AgentWorkforce/relay8872026년 10월 18일 업데이트

AgentWorkforce의 스킬 모두 보기

이 스킬의 문제 신고