diff --git a/CHANGES b/CHANGES
index 225a8cd..ac17961 100644
--- a/CHANGES
+++ b/CHANGES
@@ -49,6 +49,9 @@ Features:
 	queue before starting to transfer data.
 	Test: LINUX_POSIXMQ_FLUSH
 
+	New options posixmq-maxmsg, posixmq-msgsize.
+	Tests: POSIXMQ_MAXMSG POSIXMQ_MSGSIZE
+
 Building:
 	Disabling certain features during configure could break build process.
 
diff --git a/doc/socat.yo b/doc/socat.yo
index a478fbb..3786ebd 100644
--- a/doc/socat.yo
+++ b/doc/socat.yo
@@ -2168,7 +2168,7 @@ label(OPTION_NETNS)dit(bf(tt(netns=<net-namespace-name>)))
    Before opening the address it tries to switch to the named network namespace.
    After opening the address it switches back to the previous namespace.
    (link(Example with TCP forwarder)(EXAMPLE_OPTION_NETNS),
-   link(example with virtual network connection)(EXAMPLE_TUN_NETNS).nl()
+   link(example with virtual network connection)(EXAMPLE_TUN_NETNS)).nl()
    Only on Linux; requires root; use option tt(--experimental).nl()
 enddit()
 
@@ -3495,6 +3495,14 @@ label(OPTION_POSIXMQ_PRIORITY)dit(bf(tt(posixmq-priority (mq-prio))))
 label(OPTION_POSIXMQ_FLUSH)dit(bf(tt(posixmq-flush (mq-flush))))
    "Consumes" (drops) all messages currently in the queue before starting
    transfers.
+label(OPTION_POSIXMQ_MAXMSG)dit(bf(tt(posixmq-maxmsg (mq-maxmsg))))
+   Sets the maxmsg parameter of the POSIX message queue when creating it.
+   Note: You need root or CAP_SYS_RESOURCE to exceed the default value
+   (<tt>/proc/sys/fs/mqueue/msg_default</tt>).
+label(OPTION_POSIXMQ_MSGSIZE)dit(bf(tt(posixmq-msgsize (mq-msgsize))))
+   Sets the msgsize parameter of the POSIX message queue when creating it.
+   Note: You need root or CAP_SYS_RESOURCE to exceed the default value
+   (<tt>/proc/sys/fs/mqueue/msgsize_default</tt>).
 enddit()
 
 
diff --git a/test.sh b/test.sh
index 7dcb0da..3bc44e8 100755
--- a/test.sh
+++ b/test.sh
@@ -15106,8 +15106,8 @@ tf="$td/test$N.stdout"
 te="$td/test$N.stderr"
 tdiff="$td/test$N.diff"
 da="test$N $(date) $RANDOM"
-CMD0="$TRACE $SOCAT $opts TCP4-LISTEN:$PORT,reuseaddr EXEC:'$FILAN -s',nofork"
-CMD1="$TRACE $SOCAT $opts -t $T4 - TCP4:localhost:$PORT"
+CMD0="$TRACE $SOCAT $opts -t $T4 TCP4-LISTEN:$PORT,reuseaddr EXEC:'$FILAN -s',nofork"
+CMD1="$TRACE $SOCAT $opts -t $T8 - TCP4:localhost:$PORT"
 printf "test $F_n $TEST... " $N
 eval "$CMD0" >/dev/null 2>"${te}0" &
 pid0=$!
diff --git a/xio-posixmq.c b/xio-posixmq.c
index 5168781..ff5842d 100644
--- a/xio-posixmq.c
+++ b/xio-posixmq.c
@@ -25,8 +25,10 @@ const struct addrdesc xioaddr_posixmq_read    = { "POSIXMQ-READ",          1+XIO
 const struct addrdesc xioaddr_posixmq_receive = { "POSIXMQ-RECEIVE",       1+XIO_RDONLY, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD,      XIO_RDONLY, XIOREAD_RECV_ONESHOT, 0 HELP(":<mqname>") };
 const struct addrdesc xioaddr_posixmq_send    = { "POSIXMQ-SEND",          1+XIO_WRONLY, xioopen_posixmq, GROUP_FD|GROUP_NAMED|GROUP_POSIXMQ|GROUP_RETRY|GROUP_CHILD,      XIO_WRONLY, 0, 0 HELP(":<mqname>") };
 
-const struct optdesc opt_posixmq_priority   = { "posixmq-priority",   "mq-pri",   OPT_POSIXMQ_PRIORITY,   GROUP_POSIXMQ, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(para.posixmq.prio), XIO_SIZEOF(para.posixmq.prio), 0 };
+const struct optdesc opt_posixmq_priority   = { "posixmq-priority",   "mq-prio",  OPT_POSIXMQ_PRIORITY,   GROUP_POSIXMQ, PH_INIT, TYPE_BOOL, OFUNC_OFFSET, XIO_OFFSETOF(para.posixmq.prio), XIO_SIZEOF(para.posixmq.prio), 0 };
 const struct optdesc opt_posixmq_flush      = { "posixmq-flush",      "mq-flush", OPT_POSIXMQ_FLUSH,      GROUP_POSIXMQ, PH_EARLY, TYPE_BOOL, OFUNC_SPEC,   0,                               0,                             0 };
+const struct optdesc opt_posixmq_maxmsg     = { "posixmq-maxmsg",     "mq-maxmsg",  OPT_POSIXMQ_MAXMSG,   GROUP_POSIXMQ, PH_OPEN,  TYPE_LONG, OFUNC_SPEC,   0,                               0,                             0 };
+const struct optdesc opt_posixmq_msgsize    = { "posixmq-msgsize",    "mq-msgsize", OPT_POSIXMQ_MSGSIZE,  GROUP_POSIXMQ, PH_OPEN,  TYPE_LONG, OFUNC_SPEC,   0,                               0,                             0 };
 
 /* _read(): open immediately, stay in transfer loop
    _recv(): wait until data (how we know there is??), oneshot, opt.fork
@@ -47,11 +49,12 @@ static int xioopen_posixmq(
 	bool opt_unlink_early = false;
 	bool nonblock = 0;
 	bool flush = false;
+	struct mq_attr attr = { 0 };
+	bool setopts = false;
 	int oflag;
 	bool opt_o_excl = false;
 	mode_t opt_mode = 0666;
 	mqd_t mqd;
-	struct mq_attr attr;
 	int _errno;
 	bool dofork = false;
 	int maxchildren = 0;
@@ -100,6 +103,47 @@ static int xioopen_posixmq(
 	retropt_bool(opts, OPT_O_EXCL, &opt_o_excl);
 	retropt_mode(opts, OPT_PERM, &opt_mode);
 	retropt_bool(opts, OPT_POSIXMQ_FLUSH, &flush);
+	retropt_long(opts, OPT_POSIXMQ_MAXMSG,  &attr.mq_maxmsg) ||
+		(setopts = true);
+	retropt_long(opts, OPT_POSIXMQ_MSGSIZE, &attr.mq_msgsize) ||
+		(setopts = true);
+
+	/* When only one of mq-maxmsg and mq-msgsize options has been provided,
+	   we must nevertheless set the other option value in strucht mq_attr.
+	   For this we have to find the default, read it from /proc fs */
+	if (setopts) {
+		int pfd;
+		const static char *PROC_MAXMSG  = "/proc/sys/fs/mqueue/msg_default";
+		const static char *PROC_MSGSIZE = "/proc/sys/fs/mqueue/msgsize_default";
+		char buff[21]; 	/* fit a 64bit num in decimal */
+		ssize_t bytes;
+
+		if (attr.mq_maxmsg == 0) {
+			if ((pfd = Open(PROC_MAXMSG, O_RDONLY, 0)) < 0) {
+				Warn2("open(\"%s\", O_RDONLY, 0): %s", PROC_MAXMSG, strerror(errno));
+			} else if ((bytes = Read(pfd, buff, sizeof(buff)-1)) < 0) {
+				Warn4("read(%d /* \"%s\" */, buff, "F_Zd"): %s",
+				      pfd, PROC_MAXMSG, sizeof(buff)-1, strerror (errno));
+				Close(pfd);
+			} else {
+				sscanf(buff, "%ld", &attr.mq_maxmsg);
+				Close(pfd);
+			}
+		}
+
+		if (attr.mq_msgsize == 0) {
+			if ((pfd = Open(PROC_MSGSIZE, O_RDONLY, 0)) < 0) {
+				Warn2("open(\"%s\", O_RDONLY, 0): %s", PROC_MSGSIZE, strerror(errno));
+			} else if ((bytes = Read(pfd, buff, sizeof(buff)-1)) < 0) {
+				Warn4("read(%d /* \"%s\" */, buff, "F_Zd"): %s",
+				      pfd, PROC_MSGSIZE, sizeof(buff)-1, strerror (errno));
+				Close(pfd);
+			} else {
+				sscanf(buff, "%ld", &attr.mq_msgsize);
+				Close(pfd);
+			}
+		}
+	}
 
 	retropt_bool(opts, OPT_UNLINK_EARLY, &opt_unlink_early);
 	if (opt_unlink_early) {
@@ -126,12 +170,18 @@ static int xioopen_posixmq(
 	}
 
 	/* Now open the message queue */
-	Debug3("mq_open(\"%s\", %d, "F_mode", NULL)", name, oflag, opt_mode);
-	mqd = mq_open(name, oflag, opt_mode, NULL);
+	if (setopts)
+		Debug8("%s: mq_open(\"%s\", "F_mode", "F_mode", {flags=%ld, maxmsg=%ld, msgsize=%ld, curmsgs=%ld} )", argv[0], name, oflag, opt_mode, attr.mq_flags, attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs);
+	else
+		Debug4("%s: mq_open(\"%s\", "F_mode", "F_mode", NULL)", argv[0], name, oflag, opt_mode);
+	mqd = mq_open(name, oflag, opt_mode, setopts ? &attr : NULL);
 	_errno = errno;
 	Debug1("mq_open() -> %d", mqd);
 	if (mqd < 0) {
-		Error3("%s: mq_open(\"%s\"): %s", argv[0], name, strerror(errno));
+		if (setopts)
+			Error9("%s: mq_open(\"%s\", "F_mode", "F_mode", {flags=%ld, maxmsg=%ld, msgsize=%ld, curmsgs=%ld} ): %s", argv[0], name, oflag, opt_mode, attr.mq_flags, attr.mq_maxmsg, attr.mq_msgsize, attr.mq_curmsgs, strerror(errno));
+		else
+			Error5("%s: mq_open(\"%s\", "F_mode", "F_mode", NULL): %s", argv[0], name, oflag, opt_mode, strerror(errno));
 		errno = _errno;
 		return STAT_RETRYLATER;
 	}
diff --git a/xio-posixmq.h b/xio-posixmq.h
index b7242e0..4779f1a 100644
--- a/xio-posixmq.h
+++ b/xio-posixmq.h
@@ -10,6 +10,8 @@ extern const struct addrdesc xioaddr_posixmq_read;
 extern const struct addrdesc xioaddr_posixmq_receive;
 extern const struct addrdesc xioaddr_posixmq_send;
 
+extern const struct optdesc opt_posixmq_maxmsg;
+extern const struct optdesc opt_posixmq_msgsize;
 extern const struct optdesc opt_posixmq_priority;
 extern const struct optdesc opt_posixmq_flush;
 
diff --git a/xioopts.c b/xioopts.c
index 3824014..0f48c40 100644
--- a/xioopts.c
+++ b/xioopts.c
@@ -1032,8 +1032,10 @@ const struct optname optionnames[] = {
 #endif
 	IF_ANY    ("mode",	&opt_perm)
 #if WITH_POSIXMQ
-	IF_ANY	  ("mq-flush",	&opt_posixmq_flush)
-	IF_ANY	  ("mq-prio",	&opt_posixmq_priority)
+	IF_ANY	  ("mq-flush",		&opt_posixmq_flush)
+	IF_ANY	  ("mq-maxmsg",		&opt_posixmq_maxmsg)
+	IF_ANY	  ("mq-msgsize", 	&opt_posixmq_msgsize)
+	IF_ANY	  ("mq-prio",		&opt_posixmq_priority)
 #endif
 #ifdef TCP_MAXSEG
 	IF_TCP    ("mss",	&opt_tcp_maxseg)
@@ -1350,6 +1352,8 @@ const struct optname optionnames[] = {
 #endif
 #if WITH_POSIXMQ
 	IF_ANY	  ("posixmq-flush",	&opt_posixmq_flush)
+	IF_ANY	  ("posixmq-maxmsg",	&opt_posixmq_maxmsg)
+	IF_ANY	  ("posixmq-msgsize", 	&opt_posixmq_msgsize)
 	IF_ANY	  ("posixmq-priority",	&opt_posixmq_priority)
 #endif
 #if (WITH_IP4 || WITH_IP6) && HAVE_RESOLV_H && WITH_RES_PRIMARY
diff --git a/xioopts.h b/xioopts.h
index 4796fb2..2cdd3ac 100644
--- a/xioopts.h
+++ b/xioopts.h
@@ -483,6 +483,8 @@ enum e_optcode {
    OPT_MAX_CHILDREN,
 #if WITH_POSIXMQ
    OPT_POSIXMQ_FLUSH,
+   OPT_POSIXMQ_MAXMSG,
+   OPT_POSIXMQ_MSGSIZE,
    OPT_POSIXMQ_PRIORITY,
 #endif
 #ifdef NLDLY