ServerHello.ECH can exist unless when the server responds to inner CH
diff --git a/include/picotls.h b/include/picotls.h
index 42b67a3..95ab0a3 100644
--- a/include/picotls.h
+++ b/include/picotls.h
@@ -212,6 +212,7 @@
 #define PTLS_ALERT_INTERNAL_ERROR 80
 #define PTLS_ALERT_USER_CANCELED 90
 #define PTLS_ALERT_MISSING_EXTENSION 109
+#define PTLS_ALERT_UNSUPPORTED_EXTENSION 110
 #define PTLS_ALERT_UNRECOGNIZED_NAME 112
 #define PTLS_ALERT_CERTIFICATE_REQUIRED 116
 #define PTLS_ALERT_NO_APPLICATION_PROTOCOL 120
diff --git a/lib/picotls.c b/lib/picotls.c
index e73e446..50be732 100644
--- a/lib/picotls.c
+++ b/lib/picotls.c
@@ -379,13 +379,13 @@
 struct st_ptls_server_hello_t {
     uint8_t random_[PTLS_HELLO_RANDOM_SIZE];
     ptls_iovec_t legacy_session_id;
+    ptls_iovec_t ech;
     int is_retry_request;
     union {
         ptls_iovec_t peerkey;
         struct {
             uint16_t selected_group;
             ptls_iovec_t cookie;
-            const uint8_t *ech;
         } retry_request;
     };
 };
@@ -2467,15 +2467,12 @@
         case PTLS_EXTENSION_TYPE_ENCRYPTED_CLIENT_HELLO:
             if (sh->is_retry_request && tls->client.ech != NULL) {
                 if (end - src != 8) {
-                    ret = PTLS_ALERT_DECODE_ERROR;
+                    ret = PTLS_ALERT_ILLEGAL_PARAMETER;
                     goto Exit;
                 }
-                sh->retry_request.ech = src;
-                src = end;
-            } else {
-                ret = PTLS_ALERT_ILLEGAL_PARAMETER;
-                goto Exit;
             }
+            sh->ech = ptls_iovec_init(src, end - src);
+            src = end;
             break;
         default:
             src = end;
@@ -2614,7 +2611,7 @@
         if ((ret = key_schedule_select_one(tls->key_schedule, tls->cipher_suite, 0)) != 0)
             goto Exit;
         key_schedule_transform_post_ch1hash(tls->key_schedule);
-        if ((ret = client_ech_select_hello(tls, message, sh.retry_request.ech != NULL ? sh.retry_request.ech - message.base : 0,
+        if ((ret = client_ech_select_hello(tls, message, sh.ech.base != NULL ? sh.ech.base - message.base : 0,
                                            ECH_CONFIRMATION_HRR)) != 0)
             goto Exit;
         return handle_hello_retry_request(tls, emitter, &sh, message, properties);
@@ -2629,6 +2626,12 @@
     if ((ret = client_ech_select_hello(tls, message, confirm_hash_off, ECH_CONFIRMATION_SERVER_HELLO)) != 0)
         goto Exit;
 
+    /* When ECH is accepted, ServerHello MUST NOT contain an ECH extension (draft-15 section 5). */
+    if (tls->client.ech != NULL && sh.ech.base != NULL) {
+        ret = PTLS_ALERT_UNSUPPORTED_EXTENSION;
+        goto Exit;
+    }
+
     if (sh.peerkey.base != NULL) {
         if ((ret = tls->client.key_share_ctx->on_exchange(&tls->client.key_share_ctx, 1, &ecdh_secret, sh.peerkey)) != 0)
             goto Exit;