diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c
index c63aa1b6..c590d672 100644
--- a/libmariadb/mariadb_lib.c
+++ b/libmariadb/mariadb_lib.c
@@ -134,6 +134,7 @@ uint mysql_port=0;
 my_string mysql_unix_port=0;
 
 #define CONNECT_TIMEOUT 0
+#define MAX_PACKET_LENGTH_PRE_AUTH (1024L * 1024L)
 
 struct st_mariadb_methods MARIADB_DEFAULT_METHODS;
 
@@ -223,7 +224,8 @@ restart:
     if (net->last_errno != CR_SSL_CONNECTION_ERROR)
 #endif
     {
-      my_set_error(mysql, net->last_errno == ER_NET_PACKET_TOO_LARGE ?
+      my_set_error(mysql, (net->last_errno == CR_NET_PACKET_TOO_LARGE ||
+                           net->last_errno == ER_NET_PACKET_TOO_LARGE) ?
                    CR_NET_PACKET_TOO_LARGE:
                    CR_SERVER_LOST,
                    SQLSTATE_UNKNOWN, 0, errno);
@@ -1625,6 +1627,7 @@ MYSQL *mthd_my_real_connect(MYSQL *mysql, const char *host, const char *user,
   char *host_copy= NULL;
   struct st_host *host_list= NULL;
   int connect_attempts= 0;
+  unsigned long pre_auth_max_packet_size= 0;
 
   if (!mysql->methods)
     mysql->methods= &MARIADB_DEFAULT_METHODS;
@@ -1815,6 +1818,10 @@ restart:
   if (mysql->options.max_allowed_packet)
     net->max_packet_size= mysql->options.max_allowed_packet;
 
+  pre_auth_max_packet_size= net->max_packet_size;
+  if (net->max_packet_size > MAX_PACKET_LENGTH_PRE_AUTH)
+    net->max_packet_size= MAX_PACKET_LENGTH_PRE_AUTH;
+
   ma_pvio_keepalive(net->pvio);
   strcpy(mysql->net.sqlstate, "00000");
 
@@ -1987,6 +1994,9 @@ restart:
                              scramble_plugin, db))
     goto error;
 
+  /* authentication succeeded, restore the configured packet limit */
+  net->max_packet_size= pre_auth_max_packet_size;
+
   if (mysql->client_flag & CLIENT_COMPRESS ||
       mysql->client_flag & CLIENT_ZSTD_COMPRESSION)
   {
diff --git a/unittest/libmariadb/connection.c b/unittest/libmariadb/connection.c
index bd6b0486..f104eb09 100644
--- a/unittest/libmariadb/connection.c
+++ b/unittest/libmariadb/connection.c
@@ -27,6 +27,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 
 #include "my_test.h"
 
+#ifndef _WIN32
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#endif
+
 static int test_conc66(MYSQL *my)
 {
   MYSQL *mysql;
@@ -761,6 +767,111 @@ int test_connection_timeout3(MYSQL *unused __attribute__((unused)))
   return OK;
 }
 
+static my_socket conc835_listen_sock= INVALID_SOCKET;
+
+#ifndef _WIN32
+static void *conc835_rogue_server(void *arg)
+#else
+static DWORD WINAPI conc835_rogue_server(LPVOID arg)
+#endif
+{
+  my_socket client;
+  char header[4]= {(char)0xff, (char)0xff, (char)0xff, (char)0x00};
+
+  (void)arg;
+  client= accept(conc835_listen_sock, NULL, NULL);
+  if (client != INVALID_SOCKET)
+  {
+    send(client, header, (int)sizeof(header), 0);
+    closesocket(client);
+  }
+#ifndef _WIN32
+  return NULL;
+#else
+  return 0;
+#endif
+}
+
+static int test_conc835(MYSQL *unused __attribute__((unused)))
+{
+  struct sockaddr_in addr;
+  size_socket addrlen= sizeof(addr);
+  unsigned short srv_port;
+  MYSQL *mysql;
+  unsigned int connect_errno;
+  unsigned int connect_timeout= 10;
+#ifndef _WIN32
+  pthread_t thread;
+#else
+  HANDLE hthread;
+  DWORD thread_id;
+#endif
+
+  conc835_listen_sock= socket(AF_INET, SOCK_STREAM, 0);
+  if (conc835_listen_sock == INVALID_SOCKET)
+  {
+    diag("Could not create listening socket");
+    return SKIP;
+  }
+
+  memset(&addr, 0, sizeof(addr));
+  addr.sin_family= AF_INET;
+  addr.sin_addr.s_addr= htonl(INADDR_LOOPBACK);
+  addr.sin_port= 0; /* let the OS pick an ephemeral port */
+
+  if (bind(conc835_listen_sock, (struct sockaddr *)&addr, sizeof(addr)) != 0 ||
+      listen(conc835_listen_sock, 1) != 0 ||
+      getsockname(conc835_listen_sock, (struct sockaddr *)&addr, &addrlen) != 0)
+  {
+    diag("Could not set up listening socket");
+    closesocket(conc835_listen_sock);
+    return SKIP;
+  }
+  srv_port= ntohs(addr.sin_port);
+  diag("rogue server listening on 127.0.0.1:%u", srv_port);
+
+#ifndef _WIN32
+  if (pthread_create(&thread, NULL, conc835_rogue_server, NULL) != 0)
+  {
+    diag("Could not start rogue server thread");
+    closesocket(conc835_listen_sock);
+    return SKIP;
+  }
+#else
+  hthread= CreateThread(NULL, 0, conc835_rogue_server, NULL, 0, &thread_id);
+  if (!hthread)
+  {
+    diag("Could not start rogue server thread");
+    closesocket(conc835_listen_sock);
+    return SKIP;
+  }
+#endif
+
+  mysql= mysql_init(NULL);
+  mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, &connect_timeout);
+
+  /* The connection must fail: a pre-auth multipart (16 MB) packet is refused
+     before the body is ever read, so the client cannot be driven to OOM. */
+  if (mysql_real_connect(mysql, "127.0.0.1", "user", "pass", NULL,
+                         srv_port, NULL, 0))
+    diag("connection unexpectedly succeeded");
+  connect_errno= mysql_errno(mysql);
+  diag("connect rejected: (%u) %s", connect_errno, mysql_error(mysql));
+  mysql_close(mysql);
+
+#ifndef _WIN32
+  pthread_join(thread, NULL);
+#else
+  WaitForSingleObject(hthread, INFINITE);
+  CloseHandle(hthread);
+#endif
+  closesocket(conc835_listen_sock);
+
+  FAIL_UNLESS(connect_errno == CR_NET_PACKET_TOO_LARGE,
+              "expected CR_NET_PACKET_TOO_LARGE for a pre-auth multipart packet");
+  return OK;
+}
+
 
 /* test should run with valgrind */
 static int test_conc118(MYSQL *mysql)
@@ -2581,6 +2692,7 @@ struct my_tests_st my_tests[] = {
   {"test_connection_timeout", test_connection_timeout, TEST_CONNECTION_NONE, 0, NULL, NULL},
   {"test_connection_timeout2", test_connection_timeout2, TEST_CONNECTION_NONE, 0, NULL, NULL},
   {"test_connection_timeout3", test_connection_timeout3, TEST_CONNECTION_NONE, 0, NULL, NULL},
+  {"test_conc835", test_conc835, TEST_CONNECTION_NONE, 0, NULL, NULL},
   {NULL, NULL, 0, 0, NULL, NULL}
 };
 
