Hello I've been facing a weird problem the past few days. I send out a demo of my app to a few people. however for around 75% of the people the demo didn't work, while for the other 25% it works great. (even for myself)
so I investigated and found the issue. the mayority is getting the following error when connecting to the web-socket: Caused by: java.security.cert.CertificateException: No subject alternative names matching IP address 45.116.104.89 found
Full stack trace:
[21:48:31] [pool-4-thread-1/INFO]: [com.heckvision.bingosplash.web.WebSocketManager:lambda$tryStartConnection$0:48]: Attempting to connect to WebSocket...
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:77]: WebSocket error:
[21:48:32] [WebSocketWriteThread-107/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:77]: WebSocket error:
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative names matching IP address 45.116.104.89 found
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]: at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]: at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]: at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]: at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]: at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1497)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]: at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:212)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]: at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]: at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]: at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]: at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]: at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:928)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]: at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]: at java.io.InputStream.read(InputStream.java:101)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]: at com.heckvision.shadowed.java_websocket.client.WebSocketClient.run(WebSocketClient.java:543)
[21:48:32] [WebSocketConnectReadThread-106/INFO]: [com.heckvision.bingosplash.web.WebSocketManager$1:onError:78]: at java.lang.Thread.run(Thread.java:745)
[21:48:32] [WebSocketConnectReadThread-106/INFO]:
after researching I found out that this error means that the SSL certificate is not valid. this is weird since I have a valid 'lets encrypt' cert and domain. and the other 25% can connect proving the cert is valid.
the error shows I'm connecting directly to a raw IP but I'm not. im using wss://testserver.heckvision.com this domain is linked to a freshly setup test server for this demo. running nginx (for upgrading to wss) and docker (to host the web-socket)
the project is on JAVA 8. I've tried multiple versions of JAVA 8 and sorts, but nothing seems to help.
even weirder is that when I used the same class in a JAVA 21 project it works great and for 100% of the people.
I use the following java class to connect to the web-socket:
package com.heckvision.bingosplash.web;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.enums.ReadyState;
import org.java_websocket.handshake.ServerHandshake;
import javax.net.ssl.SSLContext;
import java.net.URI;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class WebSocketManager {
private final URI serverUri;
private volatile WebSocketClient client; // Made volatile for thread safety
private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
private volatile boolean shouldConnect = false; // Made volatile for thread safety
private volatile boolean connecting = false; // Made volatile for thread safety
private MessageListener messageListener;
public void setMessageListener(MessageListener listener) {
this.messageListener = listener;
}
public WebSocketManager(String serverUrl) {
this.serverUri = URI.create(serverUrl);
}
public void setShouldConnect(boolean shouldConnect) {
this.shouldConnect = shouldConnect;
if (shouldConnect) {
tryStartConnection();
} else {
disconnect();
}
}
private void tryStartConnection() {
if (client != null && client.getReadyState() == ReadyState.OPEN) return;
if (connecting) return;
connecting = true;
executor.execute(() -> {
try {
System.out.println("Attempting to connect to WebSocket...");
WebSocketClient socket = new WebSocketClient(serverUri) {
@Override
public void onOpen(ServerHandshake handshakedata) {
System.out.println("WebSocket connected.");
connecting = false; // Connection successful, clear connecting flag
}
@Override
public void onMessage(String message) {
System.out.println("Received: " + message);
if (messageListener != null) {
messageListener.onMessage(message);
}
}
@Override
public void onClose(int code, String reason, boolean remote) {
System.out.println("WebSocket closed: " + reason);
client = null;
connecting = false;
if (shouldConnect) {
scheduleReconnect();
}
}
@Override
public void onError(Exception ex) {
System.err.println("WebSocket error:");
ex.printStackTrace();
client = null;
connecting = false;
if (shouldConnect) {
scheduleReconnect();
}
}
};
SSLContext sslContext = SSLContext.getDefault();
socket.setSocketFactory(sslContext.getSocketFactory());
client = socket;
socket.connect(); // Non-blocking
} catch (Exception e) {
System.err.println("WebSocket connect exception:");
e.printStackTrace();
connecting = false;
// FIX: Only reconnect if we should still be connecting
if (shouldConnect) {
scheduleReconnect();
}
}
});
}
private void scheduleReconnect() {
executor.schedule(this::tryStartConnection, 5, TimeUnit.SECONDS);
}
private void disconnect() {
if (client != null && (client.getReadyState() == ReadyState.OPEN || client.getReadyState() == ReadyState.NOT_YET_CONNECTED)) {
try {
client.close();
System.out.println("WebSocket disconnected by request.");
} catch (Exception e) {
System.err.println("WebSocket disconnect exception:");
e.printStackTrace();
}
}
client = null;
}
public void shutdown() {
shouldConnect = false;
disconnect();
executor.shutdownNow();
}
}
- multiple versions and sorts of java - did not help
- multiple pc and operating systems - did not help
- adding custom ssl handshake checker - did not work and eventually came back wit the same error
- hosting websocket on another server - did not work same error
https://45.116.104.89.