Hi Aki, Dovecot developers
so this is a bug in dovecot 2.4 which prevents iteration over 1000s of
users with doveadm and -A flag. The workaround as identified by Philip
is to do iteration outside dovecot and then feed that into doveadm with
-u flag.
Maybe it's not such a big issue for Dovecot CE where user bases may be
low enough not to run into it. Could be of more of interest for large
users bases and Dovecot Pro. The effect is that doveadm quota recalc and
index does not terminate correctly.
It was working on dovecot 2.3 and the code hasn't really undergone that
much change.
My assumption is that in auth/auth-master-connection.c, in the
master_input_list_callback() function where there is a call
o_stream_flush(ctx->conn->output), that this call no longer appears to
reduce the o_stream_get_buffer_used_size under the MAX_OUTBUF_SIZE limit
and so get into a case with the code did not handle correctly.
This patch seems to fix it in Dovecot 2.4 by always
calling userdb_blocking_iter_next(ctx->iter) regardless of used buffer
size. I admit though that this may not be the right fix, if the
difference in the way o_stream_flush works is the root cause.
--- auth/auth-master-connection.c.orig 2026-03-08 18:06:28.025317016
+0000
+++ auth/auth-master-connection.c 2026-03-08 18:07:08.590631101 +0000
@@ -570,10 +570,9 @@
master_input_list_finish(ctx);
return;
}
- if (o_stream_get_buffer_used_size(ctx->conn->conn.output) <
MAX_OUTBUF_SIZE)
- userdb_blocking_iter_next(ctx->iter);
- else
+ if (o_stream_get_buffer_used_size(ctx->conn->conn.output) >=
MAX_OUTBUF_SIZE)
o_stream_uncork(ctx->conn->conn.output);
+ userdb_blocking_iter_next(ctx->iter);
}
static int master_input_list(struct auth_master_connection *conn,
John
On 01/03/2026 16:36, John Fawcett via dovecot wrote:
Hi
I can confirm the issue of these iteration operation not completing for
1000's of users is linked to:
MAX_OUTBUF_SIZE defined in auth/auth-master-connection.c
I made it 1024000 and managed to complete quota recalc for 10000 users.
But that's not going to be a solution, since whatever it is set to
provides a hard coded limit to how many users can be iterated for quota
get, quota recalc and index operations. Surprisingly it is not a
completely deterministic limit, since sometimes more users get processed
than other times. I was looking for a time based limit before I thought of
looking at the buffer size.
The strange thing is that the current value hasn't changed in more than 20
years if ever, so that does not explain of itself why this issue arose now
in 2.4.
#define MAX_OUTBUF_SIZE (1024*50)
The likely explanation is that exceeding the buffer size is now being
handled differently to before.
John
_______________________________________________
dovecot mailing list -- [email protected]
To unsubscribe send an email to [email protected]