TooTallNate/Java-WebSocket · error · IllegalStateException

WebSocketClient objects are not reuseable

Error message

WebSocketClient objects are not reuseable

What it means

Thrown by WebSocketClient.connect() when connectReadThread is still non-null, meaning connect() (or a reconnect) was already called and the previous connection lifecycle has not been torn down. WebSocketClient is single-use per connect cycle: it keeps references to its threads and latches, so a second connect on the same instance is rejected instead of corrupting state.

Solutions

  1. Create a new WebSocketClient instance for each (re)connection instead of calling connect() twice.
  2. Use client.reconnect() or reconnectBlocking(), which reset the internal state and create fresh latches and engine.
  3. Ensure a prior connect failed fully (threads joined) before re-attempting; otherwise the stale connectReadThread triggers this error.
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/main/java/org/java_websocket/client/WebSocketClient.java:394 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at src/main/java/org/java_websocket/client/WebSocketClient.java:394

        this.socket.close();
        this.socket = null;
      }
    } catch (Exception e) {
      onError(e);
      engine.closeConnection(CloseFrame.ABNORMAL_CLOSE, e.getMessage());
      return;
    }
    connectLatch = new CountDownLatch(1);
    closeLatch = new CountDownLatch(1);
    this.engine = new WebSocketImpl(this, this.draft);
  }

  /**
   * Initiates the websocket connection. This method does not block.
   */
  public void connect() {
    if (connectReadThread != null) {
      throw new IllegalStateException("WebSocketClient objects are not reuseable");
    }
    connectReadThread = new Thread(this);
    connectReadThread.setDaemon(isDaemon());
    connectReadThread.setName("WebSocketConnectReadThread-" + connectReadThread.getId());
    connectReadThread.start();
  }

  /**
   * Same as <code>connect</code> but blocks until the websocket connected or failed to do so.<br>
   *
   * @return Returns whether it succeeded or not.
   * @throws InterruptedException Thrown when the threads get interrupted
   */
  public boolean connectBlocking() throws InterruptedException {
    connect();
    connectLatch.await();
    return engine.isOpen();
  }

View on GitHub (pinned to afeacbf8c0)