TooTallNate/Java-WebSocket · error · InvalidFrameException
1007
1007
Error message
Control frame can't have rsv1==true set
What it means
RSV bits are reserved for extensions; a control frame must have RSV1/RSV2/RSV3 all zero unless a negotiated extension explicitly defines control-frame usage (permessage-deflate does not). ControlFrame.isValid throws InvalidFrameException when RSV1 is set on a control frame.
Solutions
- Fix the peer so control frames are never compressed and RSV1 stays 0 (per RFC 7692, only data frames are compressed).
- If building frames manually, leave rsv1/rsv2/rsv3 false for control frames.
- Verify which extensions were negotiated — no standard WebSocket extension sets RSV1 on control frames.
- Log raw frame headers to identify the offending peer implementation.
Example fix
// before: compressing a ping like a data frame Framedata ping = new FramedataImpl1(Opcode.PING); ping.setRSV1(true); // invalid for control frames // after Framedata ping = new FramedataImpl1(Opcode.PING); ping.setRSV1(false);
Defensive patterns
Strategy: validation
Validate before calling
// control frames must not carry RSV bits
if (isControlOpcode(frame.getOpcode()) && (frame.isRSV1() || frame.isRSV2() || frame.isRSV3())) {
throw new IllegalArgumentException("control frames must not set RSV bits");
} Try / catch
try {
validateFrame(frame);
} catch (InvalidFrameException e) {
logger.warn("control frame with RSV bits from peer: {}", e.getMessage());
webSocket.close(1002, "protocol error");
} Prevention
- Never compress control frames even when permessage-deflate is negotiated
- Leave RSV1/2/3 false on all control frames
- Verify peer implementations with an interop test suite
When it happens
Trigger: A ping, pong, or close frame arrives with RSV1 set — e.g. a peer wrongly applying the permessage-deflate RSV1 compression flag to control frames, or a frame builder setting extension bits indiscriminately.
Common situations: Clients that compress all frames including pings after negotiating permessage-deflate; custom/patched frame serialization; fuzzed input testing the endpoint's strictness.
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
- bad rsv RSV1: RSV2: RSV3
- Continuous frame cannot have RSV1, RSV2 or RSV3 set
- Control frame can't have fin==false set
- more than 125 octets
- bad rsv RSV1: RSV2: RSV3
AI-assisted analysis of TooTallNate/Java-WebSocket@afeacbf8c0 (2026-09-09).
Data as JSON: /api/errors/55c0980ac67186a2.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/org/java_websocket/framing/ControlFrame.java:52
*/
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)