TooTallNate/Java-WebSocket · error · InvalidFrameException

Control frame can't have fin==false set

Error message

Control frame can't have fin==false set

What it means

Per RFC 6455, control frames (ping, pong, close) must never be fragmented: their FIN bit must be 1. ControlFrame.isValid rejects any control frame with FIN == 0 by throwing InvalidFrameException('Control frame can't have fin==false set').

Solutions

  1. Fix the peer implementation to always set FIN=1 on control frames.
  2. If building control frames yourself, construct them via the library's ping()/sendPong()/close() APIs, which set FIN correctly.
  3. Treat such traffic as a protocol violation and log/reject the peer.
  4. Use a packet capture to confirm the raw frame's FIN bit before filing a bug.

Example fix

// before: manual control frame without FIN
Framedata ping = new FramedataImpl1(Opcode.PING);
ping.setFin(false); // invalid

// after
Framedata ping = new FramedataImpl1(Opcode.PING);
ping.setFin(true);
Defensive patterns

Strategy: validation

Validate before calling

// control frames must be unfragmented
if (isControlOpcode(frame.getOpcode()) && !frame.isFin()) {
    throw new IllegalArgumentException("control frames must have FIN set");
}

Try / catch

try {
    validateFrame(frame);
} catch (InvalidFrameException e) {
    logger.warn("protocol violation from peer: {}", e.getMessage());
    webSocket.close(1002, "protocol error");
}

Prevention

When it happens

Trigger: A ping/pong/close frame arrives (or is constructed) with the FIN bit set to 0. isValid() runs when the frame is processed or prepared for sending.

Common situations: Non-conformant clients/servers fragmenting control frames; hand-rolled frame builders forgetting to set FIN; fuzzed or malicious traffic from attackers probing the endpoint.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/main/java/org/java_websocket/framing/ControlFrame.java:49

/**
 * Abstract class to represent control frames
 */
public abstract class ControlFrame extends FramedataImpl1 {

  /**
   * Class to represent a control frame
   *
   * @param opcode the opcode to use
   */
  public ControlFrame(Opcode opcode) {
    super(opcode);
  }

  @Override
  public void isValid() throws InvalidDataException {
    if (!isFin()) {
      throw new InvalidFrameException("Control frame can't have fin==false set");
    }
    if (isRSV1()) {
      throw new InvalidFrameException("Control frame can't have rsv1==true set");
    }
    if (isRSV2()) {
      throw new InvalidFrameException("Control frame can't have rsv2==true set");
    }
    if (isRSV3()) {
      throw new InvalidFrameException("Control frame can't have rsv3==true set");
    }
  }
}

View on GitHub (pinned to afeacbf8c0)