{"record":{"id":"4fcfd611be926a84","repo":"TooTallNate/Java-WebSocket","slug":"onprepareping-websocket-returned-null-pingframe","errorCode":null,"errorMessage":"onPreparePing(WebSocket) returned null. PingFrame to sent can't be null.","messagePattern":"onPreparePing\\(WebSocket\\) returned null\\. PingFrame to sent can't be null\\.","errorType":"exception","errorClass":"NullPointerException","httpStatus":null,"severity":"error","filePath":"src/main/java/org/java_websocket/WebSocketImpl.java","lineNumber":701,"sourceCode":"  public void sendFragmentedFrame(Opcode op, ByteBuffer buffer, boolean fin) {\n    send(draft.continuousFrame(op, buffer, fin));\n  }\n\n  @Override\n  public void sendFrame(Collection<Framedata> frames) {\n    send(frames);\n  }\n\n  @Override\n  public void sendFrame(Framedata framedata) {\n    send(Collections.singletonList(framedata));\n  }\n\n  public void sendPing() throws NullPointerException {\n    // Gets a PingFrame from WebSocketListener(wsl) and sends it.\n    PingFrame pingFrame = wsl.onPreparePing(this);\n    if (pingFrame == null) {\n      throw new NullPointerException(\n          \"onPreparePing(WebSocket) returned null. PingFrame to sent can't be null.\");\n    }\n    sendFrame(pingFrame);\n  }\n\n  @Override\n  public boolean hasBufferedData() {\n    return !this.outQueue.isEmpty();\n  }\n\n  public void startHandshake(ClientHandshakeBuilder handshakedata)\n      throws InvalidHandshakeException {\n    // Store the Handshake Request we are about to send\n    this.handshakerequest = draft.postProcessHandshakeRequestAsClient(handshakedata);\n\n    resourceDescriptor = handshakedata.getResourceDescriptor();\n    assert (resourceDescriptor != null);\n","sourceCodeStart":683,"sourceCodeEnd":719,"githubUrl":"https://github.com/TooTallNate/Java-WebSocket/blob/afeacbf8c0f6f6a761c9d9daed8c813dd3b8ed7d/src/main/java/org/java_websocket/WebSocketImpl.java#L683-L719","documentation":"sendPing() obtains its PingFrame from WebSocketListener.onPreparePing(WebSocket); when the listener returns null the library throws NullPointerException because a ping frame must always carry some payload/frame. The default onPreparePing returns a valid frame, so this means a custom listener overrode it incorrectly.","triggerScenarios":"Overriding onPreparePing in a WebSocketClient/WebSocketServer subclass and returning null (e.g. returning a field that was never initialized), then connection-lost detection calls sendPing().","commonSituations":"Custom ping/pong keep-alive implementations where the prepared frame field is null before the first onOpen; copy-pasted onPreparePing overrides with an unimplemented body returning null.","solutions":["Fix the onPreparePing override to always return a non-null PingFrame (e.g. new PingFrame(ByteBuffer.wrap(new byte[]{1}))).","Delete the override so the default implementation is used.","Guard the field used in onPreparePing and fall back to a default PingFrame if it is null."],"exampleFix":"// before\n@Override\npublic PingFrame onPreparePing(WebSocket conn) { return myFrame; } // myFrame is null\n// after\n@Override\npublic PingFrame onPreparePing(WebSocket conn) {\n  return myFrame != null ? myFrame : new PingFrame();\n}","handlingStrategy":"type-guard","validationCode":"PingFrame f = myFrame != null ? myFrame : new PingFrame();","typeGuard":"if (pingFrame != null) { sendFrame(pingFrame); }","tryCatchPattern":"try { conn.sendPing(); } catch (NullPointerException e) { log.error(\"onPreparePing returned null\", e); }","preventionTips":["Always return a non-null PingFrame from onPreparePing","Don't override onPreparePing unless implementing custom pings","Initialize ping-frame fields in the constructor, not lazily after onOpen"],"tags":["null-check","ping","keepalive"],"backgroundTag":"null-argument","analyzedSha":"afeacbf8c0f6f6a761c9d9daed8c813dd3b8ed7d","analyzedAt":"2026-09-09T14:39:47.546Z","contentChangedAt":"2026-09-09T14:39:47.546Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}