TooTallNate/Java-WebSocket · error · NullPointerException

onPreparePing(WebSocket) returned null. PingFrame to sent…

Error message

onPreparePing(WebSocket) returned null. PingFrame to sent can't be null.

What it means

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.

Solutions

  1. Fix the onPreparePing override to always return a non-null PingFrame (e.g. new PingFrame(ByteBuffer.wrap(new byte[]{1}))).
  2. Delete the override so the default implementation is used.
  3. Guard the field used in onPreparePing and fall back to a default PingFrame if it is null.

Example fix

// before
@Override
public PingFrame onPreparePing(WebSocket conn) { return myFrame; } // myFrame is null
// after
@Override
public PingFrame onPreparePing(WebSocket conn) {
  return myFrame != null ? myFrame : new PingFrame();
}
Defensive patterns

Strategy: type-guard

Validate before calling

PingFrame f = myFrame != null ? myFrame : new PingFrame();

Type guard

if (pingFrame != null) { sendFrame(pingFrame); }

Try / catch

try { conn.sendPing(); } catch (NullPointerException e) { log.error("onPreparePing returned null", e); }

Prevention

When it happens

Trigger: 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().

Common situations: 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.

Related errors


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

Appendix: source

Thrown at src/main/java/org/java_websocket/WebSocketImpl.java:701

  public void sendFragmentedFrame(Opcode op, ByteBuffer buffer, boolean fin) {
    send(draft.continuousFrame(op, buffer, fin));
  }

  @Override
  public void sendFrame(Collection<Framedata> frames) {
    send(frames);
  }

  @Override
  public void sendFrame(Framedata framedata) {
    send(Collections.singletonList(framedata));
  }

  public void sendPing() throws NullPointerException {
    // Gets a PingFrame from WebSocketListener(wsl) and sends it.
    PingFrame pingFrame = wsl.onPreparePing(this);
    if (pingFrame == null) {
      throw new NullPointerException(
          "onPreparePing(WebSocket) returned null. PingFrame to sent can't be null.");
    }
    sendFrame(pingFrame);
  }

  @Override
  public boolean hasBufferedData() {
    return !this.outQueue.isEmpty();
  }

  public void startHandshake(ClientHandshakeBuilder handshakedata)
      throws InvalidHandshakeException {
    // Store the Handshake Request we are about to send
    this.handshakerequest = draft.postProcessHandshakeRequestAsClient(handshakedata);

    resourceDescriptor = handshakedata.getResourceDescriptor();
    assert (resourceDescriptor != null);

View on GitHub (pinned to afeacbf8c0)