diff --git a/include/block/nbd.h b/include/block/nbd.h
index 4e7bd6342f9..9c43bcf8a26 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -405,7 +405,8 @@ NBDExport *nbd_export_find(const char *name);
 void nbd_client_new(QIOChannelSocket *sioc,
                     QCryptoTLSCreds *tlscreds,
                     const char *tlsauthz,
-                    void (*close_fn)(NBDClient *, bool));
+                    void (*close_fn)(NBDClient *, uint32_t, bool),
+                    uint32_t cookie);
 void nbd_client_get(NBDClient *client);
 void nbd_client_put(NBDClient *client);

diff --git a/blockdev-nbd.c b/blockdev-nbd.c
index 213012435f4..1ddcbd7b247 100644
--- a/blockdev-nbd.c
+++ b/blockdev-nbd.c
@@ -30,6 +30,7 @@ typedef struct NBDServerData {
 } NBDServerData;

 static NBDServerData *nbd_server;
+static uint32_t nbd_cookie; /* Generation count of nbd_server */
 static int qemu_nbd_connections = -1; /* Non-negative if this is qemu-nbd */

 static void nbd_update_server_watch(NBDServerData *s);
@@ -49,23 +50,28 @@ int nbd_server_max_connections(void)
     return nbd_server ? nbd_server->max_connections : qemu_nbd_connections;
 }

-static void nbd_blockdev_client_closed(NBDClient *client, bool ignored)
+static void nbd_blockdev_client_closed(NBDClient *client, uint32_t cookie,
+                                       bool ignored)
 {
     nbd_client_put(client);
-    assert(nbd_server->connections > 0);
-    nbd_server->connections--;
-    nbd_update_server_watch(nbd_server);
+    /* Ignore any (late) connection made under a previous server */
+    if (cookie == nbd_cookie) {
+        assert(nbd_server->connections > 0);
+        nbd_server->connections--;
+        nbd_update_server_watch(nbd_server);
+    }
 }

 static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc,
                        gpointer opaque)
 {
+    assert(nbd_server);
     nbd_server->connections++;
     nbd_update_server_watch(nbd_server);

     qio_channel_set_name(QIO_CHANNEL(cioc), "nbd-server");
     nbd_client_new(cioc, nbd_server->tlscreds, nbd_server->tlsauthz,
-                   nbd_blockdev_client_closed);
+                   nbd_blockdev_client_closed, nbd_cookie);
 }

 static void nbd_update_server_watch(NBDServerData *s)
@@ -89,6 +95,7 @@ static void nbd_server_free(NBDServerData *server)
         object_unref(OBJECT(server->tlscreds));
     }
     g_free(server->tlsauthz);
+    nbd_cookie++;

     g_free(server);
 }
diff --git a/nbd/server.c b/nbd/server.c
index 892797bb111..7c37d9753f0 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -123,7 +123,8 @@ struct NBDMetaContexts {

 struct NBDClient {
     int refcount; /* atomic */
-    void (*close_fn)(NBDClient *client, bool negotiated);
+    void (*close_fn)(NBDClient *client, uint32_t cookie, bool negotiated);
+    uint32_t close_cookie;

     QemuMutex lock;

@@ -1621,7 +1622,7 @@ static void client_close(NBDClient *client, bool negotiated)

     /* Also tell the client, so that they release their reference.  */
     if (client->close_fn) {
-        client->close_fn(client, negotiated);
+        client->close_fn(client, client->close_cookie, negotiated);
     }
 }

@@ -3207,12 +3208,14 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
 /*
  * Create a new client listener using the given channel @sioc.
  * Begin servicing it in a coroutine.  When the connection closes, call
- * @close_fn with an indication of whether the client completed negotiation.
+ * @close_fn with @cookie and an indication of whether the client completed
+ # negotiation.
  */
 void nbd_client_new(QIOChannelSocket *sioc,
                     QCryptoTLSCreds *tlscreds,
                     const char *tlsauthz,
-                    void (*close_fn)(NBDClient *, bool))
+                    void (*close_fn)(NBDClient *, uint32_t, bool),
+                    uint32_t cookie)
 {
     NBDClient *client;
     Coroutine *co;
@@ -3231,6 +3234,7 @@ void nbd_client_new(QIOChannelSocket *sioc,
     client->ioc = QIO_CHANNEL(sioc);
     object_ref(OBJECT(client->ioc));
     client->close_fn = close_fn;
+    client->close_cookie = cookie;

     co = qemu_coroutine_create(nbd_co_client_start, client);
     qemu_coroutine_enter(co);
diff --git a/qemu-nbd.c b/qemu-nbd.c
index d7b3ccab21c..3ad50eec18e 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -371,7 +371,8 @@ static int nbd_can_accept(void)

 static void nbd_update_server_watch(void);

-static void nbd_client_closed(NBDClient *client, bool negotiated)
+static void nbd_client_closed(NBDClient *client, uint32_t ignored,
+                              bool negotiated)
 {
     nb_fds--;
     if (negotiated && nb_fds == 0 && !persistent && state == RUNNING) {
@@ -390,7 +391,7 @@ static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc,

     nb_fds++;
     nbd_update_server_watch();
-    nbd_client_new(cioc, tlscreds, tlsauthz, nbd_client_closed);
+    nbd_client_new(cioc, tlscreds, tlsauthz, nbd_client_closed, 0);
 }

 static void nbd_update_server_watch(void)
