diff --git a/README.test-apps.md b/README.test-apps.md
index 60308daeafc825dc467945547d13d1c899e04362..5f4d3479e46d154f9c6bc7c78f1b374c165c0513 100644
--- a/README.test-apps.md
+++ b/README.test-apps.md
@@ -78,6 +78,16 @@ same time as drawing random circles in the mirror protocol;
 if you connect to the test server using a browser at the
 same time you will be able to see the circles being drawn.
 
+The test client supports SSL too, use
+
+```bash
+$ libwebsockets-test-client localhost --ssl -s
+```
+
+the -s tells it to accept the default selfsigned cert from the server,
+otherwise it will strictly fail the connection if there is no CA cert to
+validate the server's certificate.
+
 
 Testing simple echo
 -------------------
diff --git a/lib/client-handshake.c b/lib/client-handshake.c
index cdc49d572eabeb5a58da30f4ee0bc372f64ae6f1..01a74d786ae40d1ed8e71ca5ec132c82803282e2 100644
--- a/lib/client-handshake.c
+++ b/lib/client-handshake.c
@@ -171,6 +171,9 @@ lws_client_connect_2(struct lws *wsi)
 		 * past here, we can't simply free the structs as error
 		 * handling as oom4 does.  We have to run the whole close flow.
 		 */
+		if (!wsi->protocol)
+			wsi->protocol = &wsi->context->protocols[0];
+
 		wsi->protocol->callback(wsi, LWS_CALLBACK_WSI_CREATE,
 					wsi->user_space, NULL, 0);
 		lws_set_timeout(wsi,
diff --git a/lib/client.c b/lib/client.c
index b4cd336172eea063aa462a7ab142fd0c763a9eab..e8b65ac85010f38b1f845f760152514834f4a740 100644
--- a/lib/client.c
+++ b/lib/client.c
@@ -264,7 +264,7 @@ some_wait:
 				if (n != SSL_ERROR_NONE) {
 					lwsl_err("SSL connect error %lu: %s\n",
 						n, ERR_error_string(n, sb));
-					return 0;
+					goto bail3;
 				}
 			}
 		} else
@@ -318,7 +318,7 @@ some_wait:
 					if (n != SSL_ERROR_NONE) {
 						lwsl_err("SSL connect error %lu: %s\n",
 							 n, ERR_error_string(n, sb));
-						return 0;
+						goto bail3;
 					}
 				}
 			}
@@ -343,7 +343,7 @@ some_wait:
 						 n, ERR_error_string(n, sb));
 					lws_close_free_wsi(wsi,
 						LWS_CLOSE_STATUS_NOSTATUS);
-					return 0;
+					return -1;
 				}
 			}
 #endif /* USE_WOLFSSL */
@@ -462,6 +462,10 @@ some_wait:
 
 bail3:
 		lwsl_info("closing conn at LWS_CONNMODE...SERVER_REPLY\n");
+		wsi->context->protocols[0].callback(wsi,
+				LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
+				wsi->user_space, NULL, 0);
+
 		lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
 		return -1;
 
diff --git a/lib/service.c b/lib/service.c
index c0820c69206278222771e284c930c7e9f448743a..ceab37a61437a4f90902a100c3cdf8a46148835e 100644
--- a/lib/service.c
+++ b/lib/service.c
@@ -325,6 +325,10 @@ lws_service_timeout_check(struct lws *wsi, unsigned int sec)
 		 * cleanup like flush partials.
 		 */
 		wsi->socket_is_permanently_unusable = 1;
+		if (wsi->mode == LWSCM_WSCL_WAITING_SSL)
+			wsi->context->protocols[0].callback(wsi,
+					LWS_CALLBACK_CLIENT_CONNECTION_ERROR,
+					wsi->user_space, NULL, 0);
 		lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS);
 
 		return 1;
diff --git a/test-server/test-client.c b/test-server/test-client.c
index 2f6ea10e23f345b53ba1c265bc37bc76920c43dc..c26be7f2b7caa0b7c245434f8935546b2e8f5b45 100644
--- a/test-server/test-client.c
+++ b/test-server/test-client.c
@@ -335,7 +335,15 @@ int main(int argc, char **argv)
 	if (!strcmp(prot, "http") || !strcmp(prot, "ws"))
 		use_ssl = 0;
 	if (!strcmp(prot, "https") || !strcmp(prot, "wss"))
-		use_ssl = 1;
+		if (!use_ssl)
+			use_ssl = 1;
+
+	if (use_ssl) {
+		if (use_ssl == 1)
+			lwsl_notice(" Cert must validate correctly (use -s to allow selfsigned)\n");
+		else
+			lwsl_notice(" Selfsigned certs allowed\n");
+	}
 
 	/*
 	 * create the websockets context.  This tracks open connections and