diff --git a/block/nbd.c b/block/nbd.c
index 3b133ed..f9dfe57 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -36,19 +36,35 @@
 #include "qapi/qmp/qjson.h"
 #include "qapi/qmp/qint.h"
 #include "qapi/qmp/qstring.h"
+#include "qapi/qmp/qbool.h"
 #include "qemu/cutils.h"
 
 #define EN_OPTSTR "exportname"
+#define ZI_OPTSTR "zero-init"
 
-#define PATH_PARAM      (1u << 0)
+#define PATH_PARAM      (1u << 0)
+#define ZERO_INIT_PARAM (1u << 1)
 
 typedef struct BDRVNBDState {
     NbdClientSession client;
 
     /* For nbd_refresh_filename() */
     char *path, *host, *port, *export, *tlscredsid;
+    bool zero_init;
 } BDRVNBDState;
 
+static bool set_option_zero_init(QDict *options, const char *value)
+{
+    if (strcmp(value, "on") == 0) {
+        qdict_put(options, "zero-init", qbool_from_bool(true));
+    } else if (strcmp(value, "off") == 0) {
+        qdict_put(options, "zero-init", qbool_from_bool(false));
+    } else {
+        return false;
+    }
+    return true;
+}
+
 /*
  * helpers for dealing with option parsing
  * to ease futher params adding and managing
@@ -69,7 +85,13 @@ static bool parse_query_params(QueryParams *qp, QDict *options,
             qdict_put(options, "path", qstring_from_str(param->value));
             continue;
         }
-
+        if ((ZERO_INIT_PARAM & param_flags) &&
+            strcmp(param->name, "zero-init") == 0) {
+            if (!set_option_zero_init(options, param->value)) {
+                return false;
+            }
+            continue;
+        }
     }
     return true;
 }
@@ -123,13 +145,13 @@ static int nbd_parse_uri(const char *filename, QDict *options)
     qp = query_params_parse(uri->query);
 
     if (is_unix) {
-        /* nbd+unix:///export?socket=path */
+        /* nbd+unix:///export?socket=path{,zero-init=[on|off]} */
         if (uri->server || uri->port) {
             ret = -EINVAL;
             goto out;
         }
 
-        if (!parse_query_params(qp, options, PATH_PARAM)) {
+        if (!parse_query_params(qp, options, PATH_PARAM | ZERO_INIT_PARAM)) {
             ret = -EINVAL;
             goto out;
         }
@@ -160,6 +182,11 @@ static int nbd_parse_uri(const char *filename, QDict *options)
             ret = -EINVAL;
             goto out;
         }
+
+        if (!parse_query_params(qp, options, ZERO_INIT_PARAM)) {
+            ret = -EINVAL;
+            goto out;
+        }
     }
 
 out:
@@ -187,6 +214,8 @@ static void nbd_parse_filename(const char *filename, QDict *options,
         return;
     }
 
+    set_option_zero_init(options, "off");
+
     if (strstr(filename, "://")) {
         int ret = nbd_parse_uri(filename, options);
         if (ret < 0) {
@@ -266,6 +295,11 @@ static void nbd_parse_filename(const char *filename, QDict *options,
                     .type = QEMU_OPT_STRING,
                     .help = "Name of the NBD export to open",
                 },
+                {
+                    .name = ZI_OPTSTR,
+                    .type = QEMU_OPT_BOOL,
+                    .help = "Zero-initialized image flag",
+                },
             },
         };
 
@@ -289,6 +323,11 @@ static void nbd_parse_filename(const char *filename, QDict *options,
             qdict_put(options, "export", qstring_from_str(value));
         }
 
+        value = qemu_opt_get(opts, ZI_OPTSTR);
+        if (value) {
+            qdict_put(options, ZI_OPTSTR,
+                      qbool_from_bool(strcmp(value, "on") == 0));
+        }
         qemu_opts_del(opts);
     }
 
@@ -337,6 +376,8 @@ static SocketAddress *nbd_config(BDRVNBDState *s, QemuOpts *opts, Error **errp)
 
     s->export = g_strdup(qemu_opt_get(opts, "export"));
 
+    s->zero_init = strcmp(qemu_opt_get(opts, "zero-init"), "on") == 0;
+
     return saddr;
 }
 
@@ -427,6 +468,11 @@ static QemuOptsList nbd_runtime_opts = {
             .type = QEMU_OPT_STRING,
             .help = "ID of the TLS credentials to use",
         },
+        {
+            .name = "zero-init",
+            .type = QEMU_OPT_BOOL,
+            .help = "Zero-initialized image flag",
+        },
     },
 };
 
@@ -585,9 +631,19 @@ static void nbd_refresh_filename(BlockDriverState *bs, QDict *options)
                       QOBJECT(qstring_from_str(s->tlscredsid)));
     }
 
+    if (s->zero_init) {
+        qdict_put(opts, "zero-init", qbool_from_bool(true));
+    }
+
     bs->full_open_options = opts;
 }
 
+static int nbd_has_zero_init(BlockDriverState *bs)
+{
+    BDRVNBDState *s = bs->opaque;
+    return s->zero_init;
+}
+
 static BlockDriver bdrv_nbd = {
     .format_name                = "nbd",
     .protocol_name              = "nbd",
@@ -604,6 +660,7 @@ static BlockDriver bdrv_nbd = {
     .bdrv_detach_aio_context    = nbd_detach_aio_context,
     .bdrv_attach_aio_context    = nbd_attach_aio_context,
     .bdrv_refresh_filename      = nbd_refresh_filename,
+    .bdrv_has_zero_init         = nbd_has_zero_init,
 };
 
 static BlockDriver bdrv_nbd_tcp = {
@@ -622,6 +679,7 @@ static BlockDriver bdrv_nbd_tcp = {
     .bdrv_detach_aio_context    = nbd_detach_aio_context,
     .bdrv_attach_aio_context    = nbd_attach_aio_context,
     .bdrv_refresh_filename      = nbd_refresh_filename,
+    .bdrv_has_zero_init         = nbd_has_zero_init,
 };
 
 static BlockDriver bdrv_nbd_unix = {
@@ -640,6 +698,7 @@ static BlockDriver bdrv_nbd_unix = {
     .bdrv_detach_aio_context    = nbd_detach_aio_context,
     .bdrv_attach_aio_context    = nbd_attach_aio_context,
     .bdrv_refresh_filename      = nbd_refresh_filename,
+    .bdrv_has_zero_init         = nbd_has_zero_init,
 };
 
 static void bdrv_nbd_init(void)
