TooTallNate/Java-WebSocket · error · InvalidDataException

1002

1002

Error message

Continuous frame sequence not completed.

What it means

processFrame throws InvalidDataException with CloseFrame.PROTOCOL_ERROR (close code 1002) when a new data frame (non-FIN TEXT/BINARY or otherwise) arrives while a continuous (fragmented) frame sequence is still open. Per RFC 6455, while a fragmented message is in progress, only CONTINUATION frames may arrive.

Solutions

  1. Fix the peer/sender to complete each fragmented message with a FIN frame before starting a new one
  2. If sending fragments yourself, serialize sends (single writer thread / queue) so fragments are never interleaved
  3. Handle the 1002 close on the receiving side: catch InvalidDataException and log the offending peer
  4. Verify intermediate proxies preserve frame boundaries and fragmentation

Example fix

// before: interleaved sends from two threads break fragmentation
threadA.sendFragmented(bigMessage);
threadB.send("quick msg"); // protocol error on receiver
// after
synchronized (sendLock) {
  sendFragments(bigMessage); // completes with FIN
  send("quick msg");
}
Defensive patterns

Strategy: validation

Validate before calling

// before sending a new message, ensure no fragmented message is still open
if (fragmentedSendInProgress.get()) {
  throw new IllegalStateException("Cannot start a new message while a fragmented send is in progress");
}

Try / catch

// in your WebSocketListener
@Override
public void onWebsocketError(WebSocket conn, Exception ex) {
  if (ex instanceof InvalidDataException
      && ((InvalidDataException) ex).getCloseCode() == CloseFrame.PROTOCOL_ERROR) {
    log.warn("Peer violated fragmentation rules; closing with 1002");
  }
}

Prevention

When it happens

Trigger: Receiving a TEXT or BINARY frame (with FIN or not) before the previous fragmented message was terminated by a FIN frame; processFrame's currentContinuousFrame != null branch fires.

Common situations: Buggy or malicious clients interleaving messages mid-fragmentation; proxies rewriting frames; app code that sends new messages from other threads while a fragmented send is in flight (sender-side violation reflected back on strict peers).

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

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

    }
  }

  @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.");
      throw new InvalidDataException(CloseFrame.PROTOCOL_ERROR,
          "Continuous frame sequence not completed.");
    } else if (curop == Opcode.TEXT) {
      processFrameText(webSocketImpl, frame);
    } else if (curop == Opcode.BINARY) {
      processFrameBinary(webSocketImpl, frame);
    } else {
      log.error("non control or continious frame expected");
      throw new InvalidDataException(CloseFrame.PROTOCOL_ERROR,
          "non control or continious frame expected");
    }
  }

  /**
   * Process the frame if it is a continuous frame or the fin bit is not set
   *
   * @param webSocketImpl the websocket implementation to use
   * @param frame         the current frame
   * @param curop         the current Opcode

View on GitHub (pinned to afeacbf8c0)