split ECH config applicability testing (ignore upon failure) vs. ECH instatiation error (reported)
diff --git a/lib/picotls.c b/lib/picotls.c
index d810819..25159f5 100644
--- a/lib/picotls.c
+++ b/lib/picotls.c
@@ -1091,39 +1091,38 @@
     return ret;
 }
 
-static struct st_ptls_ech_client_t *client_instantiate_ech(struct decoded_ech_config_t *decoded)
+static int client_instantiate_ech(struct st_ptls_ech_client_t **ech, struct decoded_ech_config_t *decoded)
 {
-    if (decoded->kem == NULL || decoded->cipher == NULL)
-        return NULL;
-
-    struct st_ptls_ech_client_t *ech;
     ptls_buffer_t infobuf;
     uint8_t infobuf_smallbuf[256];
     int ret;
 
+    *ech = NULL;
+
     ptls_buffer_init(&infobuf, infobuf_smallbuf, sizeof(infobuf_smallbuf));
 
-    if ((ech = malloc(offsetof(struct st_ptls_ech_client_t, public_name) + decoded->public_name.len + 1)) == NULL) {
+    if ((*ech = malloc(offsetof(struct st_ptls_ech_client_t, public_name) + decoded->public_name.len + 1)) == NULL) {
         ret = PTLS_ERROR_NO_MEMORY;
         goto Exit;
     }
-    *ech = (struct st_ptls_ech_client_t){.config_id = decoded->id, .cipher = decoded->cipher, .max_name_length = decoded->max_name_length};
-    memcpy(ech->public_name, decoded->public_name.base, decoded->public_name.len);
-    ech->public_name[decoded->public_name.len] = '\0';
+    **ech = (struct st_ptls_ech_client_t){
+        .config_id = decoded->id, .cipher = decoded->cipher, .max_name_length = decoded->max_name_length};
+    memcpy((*ech)->public_name, decoded->public_name.base, decoded->public_name.len);
+    (*ech)->public_name[decoded->public_name.len] = '\0';
 
     ptls_buffer_pushv(&infobuf, ech_info_prefix.base, ech_info_prefix.len);
     ptls_buffer_pushv(&infobuf, decoded->bytes.base, decoded->bytes.len);
 
-    ret = ptls_hpke_setup_base_s(decoded->kem, decoded->cipher, &ech->enc, &ech->aead, decoded->public_key,
-                                 ptls_iovec_init(infobuf.base, infobuf.off));
+    if ((ret = ptls_hpke_setup_base_s(decoded->kem, decoded->cipher, &(*ech)->enc, &(*ech)->aead, decoded->public_key,
+                                      ptls_iovec_init(infobuf.base, infobuf.off))) != 0)
+        goto Exit;
 
 Exit:
-    if (ret != 0) {
-        if (ech != NULL)
-            client_free_ech(ech);
-        ech = NULL;
+    if (ret != 0 && *ech != NULL) {
+        client_free_ech(*ech);
+        *ech = NULL;
     }
-    return ech;
+    return ret;
 }
 
 #define ECH_CONFIRMATION_SERVER_HELLO "ech accept confirmation"
@@ -2233,8 +2232,11 @@
             properties->client.ech.configs.len != 0) {
             struct decoded_ech_config_t decoded;
             decode_ech_config_list(tls->ctx, &decoded, properties->client.ech.configs);
-            if ((tls->client.ech = client_instantiate_ech(&decoded)) != NULL)
+            if (decoded.kem != NULL && decoded.cipher != NULL) {
+                if ((ret = client_instantiate_ech(&tls->client.ech, &decoded)) != 0)
+                    goto Exit;
                 tls->ctx->random_bytes(tls->client_random.inner, PTLS_HELLO_RANDOM_SIZE);
+            }
         }
         /* setup resumption-related data. If successful, resumption_secret becomes a non-zero value. */
         if (properties->client.session_ticket.base != NULL) {