TooTallNate/Java-WebSocket · error · InvalidDataException
1002
1002
Error message
A close frame must have a closecode if it has a reason
What it means
CloseFrame.isValid enforces that a close frame carrying a reason string must have an actual close code. Close code 0 (NOCODE) is reserved for internal representation and is not valid on the wire; sending a reason with NOCODE is contradictory, so InvalidDataException(1002 PROTOCOL_ERROR) is thrown.
Solutions
- Provide a valid close code (1000, 1001, 1011, or 3000-4999) whenever a reason string is included.
- If no code is known, send NOCODE with an empty reason, or let the library generate the frame.
- Clamp/validate application close codes to the allowed ranges before calling close(code, reason).
Example fix
// before webSocket.close(0, "shutting down"); // invalid: NOCODE with reason // after webSocket.close(1000, "shutting down");
Defensive patterns
Strategy: validation
Validate before calling
// guard before calling close
if ((code == 0 || code == CloseFrame.NOCODE) && reason != null && !reason.isEmpty()) {
throw new IllegalArgumentException("a close code is required when a reason is provided");
} Try / catch
try {
webSocket.close(code, reason);
} catch (InvalidDataException e) {
logger.warn("rejected close frame: {}", e.getMessage());
webSocket.close(1000); // fall back to a valid frame
} Prevention
- Never pass 0/NOCODE together with a reason
- Default to 1000 when no specific code applies
- Validate codes at the call site of close()
When it happens
Trigger: Building a CloseFrame whose code is CloseFrame.NOCODE (0) while the reason string is non-empty, e.g. calling close with code 0 plus a message, then isValid() rejects it before sending.
Common situations: Passing 0 as the close code by default/accident along with a reason; unmapped error paths that forward raw codes; tests constructing close frames manually.
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/7a160215baefd805.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/org/java_websocket/framing/CloseFrame.java:232
* @return the message in this frame
*/
public String getMessage() {
return reason;
}
@Override
public String toString() {
return super.toString() + "code: " + code;
}
@Override
public void isValid() throws InvalidDataException {
super.isValid();
if (code == CloseFrame.NO_UTF8 && reason.isEmpty()) {
throw new InvalidDataException(CloseFrame.NO_UTF8, "Received text is no valid utf8 string!");
}
if (code == CloseFrame.NOCODE && 0 < reason.length()) {
throw new InvalidDataException(PROTOCOL_ERROR,
"A close frame must have a closecode if it has a reason");
}
//Intentional check for code != CloseFrame.TLS_ERROR just to make sure even if the code earlier changes
if ((code > CloseFrame.TLS_ERROR && code < 3000)) {
throw new InvalidDataException(PROTOCOL_ERROR, "Trying to send an illegal close code!");
}
if (code == CloseFrame.ABNORMAL_CLOSE || code == CloseFrame.TLS_ERROR
|| code == CloseFrame.NOCODE || code > 4999 || code < 1000 || code == 1004) {
throw new InvalidFrameException("closecode must not be sent over the wire: " + code);
}
}
@Override
public void setPayload(ByteBuffer payload) {
code = CloseFrame.NOCODE;
reason = "";
payload.mark();
if (payload.remaining() == 0) {View on GitHub (pinned to afeacbf8c0)