diff --git a/src/openvpn/dco.h b/src/openvpn/dco.h
index 2fe671bf..96d95c21 100644
--- a/src/openvpn/dco.h
+++ b/src/openvpn/dco.h
@@ -58,6 +58,15 @@ struct tuntap;
  */
 bool dco_available(int msglevel);
 
+
+/**
+ * Return a human readable string representing the DCO version
+ *
+ * @param gc    the garbage collector to use for any dynamic allocation
+ * @return      a pointer to the string (allocated via gc) containing the string
+ */
+const char *dco_version_string(struct gc_arena *gc);
+
 /**
  * Check whether the options struct has any option that is not supported by
  * our current dco implementation. If so print a warning at warning level
@@ -250,6 +259,12 @@ dco_available(int msglevel)
     return false;
 }
 
+static inline const char *
+dco_version_string(struct gc_arena *gc)
+{
+    return "not-compiled";
+}
+
 static inline bool
 dco_check_option(int msglevel, const struct options *o)
 {
diff --git a/src/openvpn/dco_freebsd.c b/src/openvpn/dco_freebsd.c
index 92de5f04..cbd2ce20 100644
--- a/src/openvpn/dco_freebsd.c
+++ b/src/openvpn/dco_freebsd.c
@@ -614,6 +614,12 @@ out:
     return available;
 }
 
+const char *
+dco_version_string(struct gc_arena *gc)
+{
+    return "v0";
+}
+
 void
 dco_event_set(dco_context_t *dco, struct event_set *es, void *arg)
 {
diff --git a/src/openvpn/dco_linux.c b/src/openvpn/dco_linux.c
index 308abfc4..9f3531d5 100644
--- a/src/openvpn/dco_linux.c
+++ b/src/openvpn/dco_linux.c
@@ -841,9 +841,36 @@ dco_available(int msglevel)
             "Note: Kernel support for ovpn-dco missing, disabling data channel offload.");
         return false;
     }
+
     return true;
 }
 
+const char *
+dco_version_string(struct gc_arena *gc)
+{
+    struct buffer out = alloc_buf_gc(256, gc);
+    FILE *fp = fopen("/sys/module/ovpn_dco_v2/version", "r");
+    if (!fp)
+    {
+        return "N/A";
+    }
+
+    if (!fgets(BSTR(&out), BCAP(&out), fp))
+    {
+        return "ERR";
+    }
+
+    /* remove potential newline at the end of the string */
+    char *str = BSTR(&out);
+    char *nl = strchr(str, '\n');
+    if (nl)
+    {
+        *nl = '\0';
+    }
+
+    return BSTR(&out);
+}
+
 void
 dco_event_set(dco_context_t *dco, struct event_set *es, void *arg)
 {
diff --git a/src/openvpn/dco_win.c b/src/openvpn/dco_win.c
index a805c2a0..26463b38 100644
--- a/src/openvpn/dco_win.c
+++ b/src/openvpn/dco_win.c
@@ -385,6 +385,12 @@ dco_available(int msglevel)
     return false;
 }
 
+const char *
+dco_version_string(struct gc_arena *gc)
+{
+    return "v0";
+}
+
 int
 dco_do_read(dco_context_t *dco)
 {
diff --git a/src/openvpn/openvpn.c b/src/openvpn/openvpn.c
index cba58276..1aaddcdf 100644
--- a/src/openvpn/openvpn.c
+++ b/src/openvpn/openvpn.c
@@ -262,6 +262,8 @@ openvpn_main(int argc, char *argv[])
 #endif
             show_library_versions(M_INFO);
 
+            show_dco_version(M_INFO);
+
             /* misc stuff */
             pre_setup(&c.options);
 
diff --git a/src/openvpn/options.c b/src/openvpn/options.c
index ce7bd0a7..8f0e2194 100644
--- a/src/openvpn/options.c
+++ b/src/openvpn/options.c
@@ -4816,6 +4816,16 @@ show_windows_version(const unsigned int flags)
 }
 #endif
 
+void
+show_dco_version(const unsigned int flags)
+{
+#ifdef ENABLE_DCO
+    struct gc_arena gc = gc_new();
+    msg(flags, "DCO version: %s", dco_version_string(&gc));
+    gc_free(&gc);
+#endif
+}
+
 void
 show_library_versions(const unsigned int flags)
 {
@@ -4839,6 +4849,7 @@ usage_version(void)
 #ifdef _WIN32
     show_windows_version( M_INFO|M_NOPREFIX );
 #endif
+    show_dco_version(M_INFO | M_NOPREFIX);
     msg(M_INFO|M_NOPREFIX, "Originally developed by James Yonan");
     msg(M_INFO|M_NOPREFIX, "Copyright (C) 2002-2023 OpenVPN Inc <sales@openvpn.net>");
 #ifndef ENABLE_SMALL
diff --git a/src/openvpn/options.h b/src/openvpn/options.h
index 7df717f7..2f25f5d0 100644
--- a/src/openvpn/options.h
+++ b/src/openvpn/options.h
@@ -796,6 +796,8 @@ void show_windows_version(const unsigned int flags);
 
 #endif
 
+void show_dco_version(const unsigned int flags);
+
 void init_options(struct options *o, const bool init_gc);
 
 void uninit_options(struct options *o);
