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
- Fix the peer implementation to always set FIN=1 on control frames.
- If building control frames yourself, construct them via the library's ping()/sendPong()/close() APIs, which set FIN correctly.
- Treat such traffic as a protocol violation and log/reject the peer.
- 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
- Use the library's ping()/sendPong()/close() helpers instead of raw frames
- Reject fragmented control frames as a protocol violation
- Fuzz-test your endpoint for malformed frame headers
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)