diff --git a/changelogs/unreleased/gh-6766-fix-error-in-extension-via-netbox.md b/changelogs/unreleased/gh-6766-fix-error-in-extension-via-netbox.md
new file mode 100644
index 0000000000000000000000000000000000000000..44aec1c7bff9274884627df4ab104cdbebd0f488
--- /dev/null
+++ b/changelogs/unreleased/gh-6766-fix-error-in-extension-via-netbox.md
@@ -0,0 +1,3 @@
+## bugfix/sql
+
+* Fixed assertion or segfault when MP_EXT received via net.box (gh-6766).
diff --git a/src/box/bind.c b/src/box/bind.c
index aff2d3d76dcaf9169a6a622329f41b97fbc5ab24..6b7f9365dc6c7355ea4b142b140cf3ff8b723c25 100644
--- a/src/box/bind.c
+++ b/src/box/bind.c
@@ -34,6 +34,9 @@
 #include "sql/sqlInt.h"
 #include "sql/sqlLimit.h"
 #include "sql/vdbe.h"
+#include "mp_datetime.h"
+#include "mp_decimal.h"
+#include "mp_uuid.h"
 
 const char *
 sql_bind_name(const struct sql_bind *bind)
@@ -99,9 +102,41 @@ sql_bind_decode(struct sql_bind *bind, int i, const char **packet)
 	case MP_BIN:
 		bind->s = mp_decode_bin(packet, &bind->bytes);
 		break;
+	case MP_EXT: {
+		int8_t ext_type;
+		uint32_t size = mp_decode_extl(packet, &ext_type);
+		switch (ext_type) {
+		case MP_UUID:
+			if (uuid_unpack(packet, size, &bind->uuid) == NULL) {
+				diag_set(ClientError, ER_INVALID_MSGPACK,
+					 "Invalid MP_UUID MsgPack format");
+				return -1;
+			}
+			break;
+		case MP_DECIMAL:
+			if (decimal_unpack(packet, size, &bind->dec) == NULL) {
+				diag_set(ClientError, ER_INVALID_MSGPACK,
+					 "Invalid MP_DECIMAL MsgPack format");
+				return -1;
+			}
+			break;
+		case MP_DATETIME:
+			if (datetime_unpack(packet, size, &bind->dt) == NULL) {
+				diag_set(ClientError, ER_INVALID_MSGPACK,
+					 "Invalid MP_DATETIME MsgPack format");
+				return -1;
+			}
+			break;
+		default:
+			diag_set(ClientError, ER_SQL_BIND_TYPE, "USERDATA",
+				 sql_bind_name(bind));
+			return -1;
+		}
+		bind->ext_type = ext_type;
+		break;
+	}
 	case MP_ARRAY:
 	case MP_MAP:
-	case MP_EXT:
 		bind->s = *packet;
 		mp_next(packet);
 		bind->bytes = *packet - bind->s;
diff --git a/test/sql-luatest/gh_6766_mp_ext_via_netbox_test.lua b/test/sql-luatest/gh_6766_mp_ext_via_netbox_test.lua
new file mode 100644
index 0000000000000000000000000000000000000000..9ea357ef1eb4b17fa19288b517908ae925aa86c1
--- /dev/null
+++ b/test/sql-luatest/gh_6766_mp_ext_via_netbox_test.lua
@@ -0,0 +1,44 @@
+local server = require('test.luatest_helpers.server')
+local t = require('luatest')
+local g = t.group()
+
+g.before_all(function()
+    g.server = server:new({alias = 'gh-6766'})
+    g.server:start()
+end)
+
+g.after_all(function()
+    g.server:stop()
+end)
+
+g.test_6766_1 = function()
+    local conn = g.server.net_box
+    local val = require('uuid').new()
+    local res = {{'uuid'}}
+    local rows = conn:execute([[SELECT typeof(?);]], {val}).rows
+    t.assert_equals(rows, res)
+end
+
+g.test_6766_2 = function()
+    local conn = g.server.net_box
+    local val = require('decimal').new(1.5)
+    local res = {{'decimal'}}
+    local rows = conn:execute([[SELECT typeof(?);]], {val}).rows
+    t.assert_equals(rows, res)
+end
+
+g.test_6766_3 = function()
+    local conn = g.server.net_box
+    local val = require('datetime').now()
+    local res = {{'datetime'}}
+    local rows = conn:execute([[SELECT typeof(?);]], {val}).rows
+    t.assert_equals(rows, res)
+end
+
+g.test_6766_4 = function()
+    local conn = g.server.net_box
+    local val = require('msgpack').object_from_raw('\xc7\x00\x0f')
+    local res = "Bind value type USERDATA for parameter 1 is not supported"
+    local _, err = pcall(conn.execute, conn, [[SELECT typeof(?);]], {val})
+    t.assert_equals(err.message, res)
+end