TooTallNate/Java-WebSocket · error · InvalidFrameException

Unknown opcode

Error message

Unknown opcode {opcode}

What it means

Draft_6455.toOpcode throws InvalidFrameException("Unknown opcode <n>") when an incoming frame header carries an opcode in the reserved range 3-7 (non-control) or 11-15 (control), which are not yet defined by RFC 6455. The library cannot interpret such a frame and rejects it as invalid.

Solutions

  1. Fix or stop the peer from sending reserved opcodes; RFC 6455 receivers must fail the connection
  2. Catch InvalidFrameException and close with protocol error (1002)
  3. Check for stream desynchronization (partial reads, wrong framing) if garbage opcodes appear
  4. Disable protocol extensions on either side that may emit unsupported opcodes
Defensive patterns

Strategy: try-catch

Try / catch

// in your WebSocketListener
@Override
public void onWebsocketError(WebSocket conn, Exception ex) {
  if (ex instanceof InvalidFrameException && ex.getMessage().startsWith("Unknown opcode")) {
    conn.close(CloseFrame.PROTOCOL_ERROR, "reserved opcode received");
  }
}

Prevention

When it happens

Trigger: Receiving a frame whose 4-bit opcode field is 3-7 or 11-15; toOpcode's switch default throws. Often from protocol-violating peers, extensions negotiating opcodes this library doesn't support, or corrupted stream data.

Common situations: Peer implementing newer/proprietary opcodes; desynchronization causing garbage bytes to be parsed as opcodes; fuzz testing; protocol extensions (e.g. permessage-deflate variants) misbehaving.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of TooTallNate/Java-WebSocket@afeacbf8c0 (2026-09-09). Data as JSON: /api/errors/d28260ce4853b48e. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/org/java_websocket/drafts/Draft_6455.java:888

  private Opcode toOpcode(byte opcode) throws InvalidFrameException {
    switch (opcode) {
      case 0:
        return Opcode.CONTINUOUS;
      case 1:
        return Opcode.TEXT;
      case 2:
        return Opcode.BINARY;
      // 3-7 are not yet defined
      case 8:
        return Opcode.CLOSING;
      case 9:
        return Opcode.PING;
      case 10:
        return Opcode.PONG;
      // 11-15 are not yet defined
      default:
        throw new InvalidFrameException("Unknown opcode " + (short) opcode);
    }
  }

  @Override
  public void processFrame(WebSocketImpl webSocketImpl, Framedata frame)
      throws InvalidDataException {
    Opcode curop = frame.getOpcode();
    if (curop == Opcode.CLOSING) {
      processFrameClosing(webSocketImpl, frame);
    } else if (curop == Opcode.PING) {
      webSocketImpl.getWebSocketListener().onWebsocketPing(webSocketImpl, frame);
    } else if (curop == Opcode.PONG) {
      webSocketImpl.updateLastPong();
      webSocketImpl.getWebSocketListener().onWebsocketPong(webSocketImpl, frame);
    } else if (!frame.isFin() || curop == Opcode.CONTINUOUS) {
      processFrameContinuousAndNonFin(webSocketImpl, frame, curop);
    } else if (currentContinuousFrame != null) {
      log.error("Protocol error: Continuous frame sequence not completed.");

View on GitHub (pinned to afeacbf8c0)