]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: limits: explain a bit better what to do when fd limits are exceeded
authorWilly Tarreau <w@1wt.eu>
Wed, 19 Nov 2025 15:38:29 +0000 (16:38 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 20 Nov 2025 07:44:52 +0000 (08:44 +0100)
As shown in github issue #3191, the error message shown when FD limits
are exceeded is not very useful as-is, since the current hard limit is
not displayed, and no suggestion is made about what to change in the
config. Let's explain about maxconn/ulimit-n/fd-hard-limit, suggest
dropping them or setting them to a context-based value at roughly 49%
of the current limit minus the known used FDs for listeners and checks.
This allows common "large" hard limits to report mostly round maxconns.
Example:

  [ALERT]    (25330) : [haproxy.main()] Cannot raise FD limit to 4001020,
  current limit is 1024 and hard limit is 4096. You may prefer to let
  HAProxy adjust the limit by itself; for this, please just drop any
  'maxconn' and 'ulimit-n' from the global section, and possibly add
  'fd-hard-limit' lower than this hard limit. You may also force a new
  'maxconn' value that is a bit lower than half of the hard limit minus
  listeners and checks. This results in roughly 1500 here.

src/limits.c

index d2aa3cffccac444260b19a9d5254fba52f1aaefe..b00cb8cc86bcc00936705939d71b36f19ddf371f 100644 (file)
@@ -454,8 +454,19 @@ void apply_nofile_limit(void)
                                limit.rlim_cur = global.fd_hard_limit;
 
                        if (global.tune.options & GTUNE_STRICT_LIMITS) {
-                               ha_alert("[%s.main()] Cannot raise FD limit to %d, limit is %d.\n",
-                                        progname, global.rlimit_nofile, (int)limit.rlim_cur);
+                               /* suggest roughly half of the limit minus used FDs for listeners, checks
+                                * etc. This will give roughly round numbers for 64k and above while
+                                * reserving enough listeners for small values such as 1024.
+                                */
+                               ha_alert("[%s.main()] Cannot raise FD limit to %d, current "
+                                        "limit is %d and hard limit is %d. You may prefer to let HAProxy "
+                                        "adjust the limit by itself; for this, please just drop any 'maxconn' and "
+                                        "'ulimit-n' from the global section, and possibly add 'fd-hard-limit' lower "
+                                        "than this hard limit. You may also force a new 'maxconn' value that is a bit "
+                                        "lower than half of the hard limit minus listeners and checks. This results in "
+                                        "roughly %u here.\n",
+                                        progname, global.rlimit_nofile, (int)limit.rlim_cur, (int)limit.rlim_max,
+                                        round_2dig((uint)MAX(limit.rlim_max - global.est_fd_usage, 3) * 49ULL / 100));
                                exit(1);
                        }
                        else {
@@ -469,6 +480,16 @@ void apply_nofile_limit(void)
 
                                ha_warning("[%s.main()] Cannot raise FD limit to %d, limit is %d.\n",
                                           progname, global.rlimit_nofile, (int)limit.rlim_cur);
+
+                               ha_warning("[%s.main()] Cannot raise FD limit to %d, current "
+                                          "limit is %d and hard limit is %d. You may prefer to let HAProxy "
+                                          "adjust the limit by itself; for this, please just drop any 'maxconn' and "
+                                          "'ulimit-n' from the global section, and possibly add 'fd-hard-limit' lower "
+                                          "than this hard limit. You may also force a new 'maxconn' value that is a bit "
+                                          "lower than half of the hard limit minus listeners and checks. This results in "
+                                          "roughly %u here.\n",
+                                          progname, global.rlimit_nofile, (int)limit.rlim_cur, (int)limit.rlim_max,
+                                          round_2dig((uint)MAX(limit.rlim_max - global.est_fd_usage, 3) * 49ULL / 100));
                                global.rlimit_nofile = limit.rlim_cur;
                        }
                }