You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
in_http: Connection: close is parsed but never acted on, connection idles to the 10s timeout #12655
Connection: close is parsed and recorded, but the connection is never closed in response to it. The response
does not carry Connection: close either, and the socket stays open until the 10 s IO timeout. A client that
sends Connection: close and waits for the close stalls for 10 seconds.
To Reproduce
POST / HTTP/1.1
Host: x
Content-Type: application/json
Connection: close
Content-Length: 7
{"a":1}
Measured: the 201 Created comes back at 0.00 s, the response has noConnection: close header, and EOF only
arrives at 10.6 s when the server times the connection out.
Root cause
The parser does record the intent — mk_http_parser.c:356 sets p->header_connection = MK_HTTP_PARSER_CONN_CLOSE,
and mk_http_keepalive_check() (mk_http.c:1135) turns that into cs->close_now = MK_TRUE.
But close_now is only ever acted on in mk_lib.c:769, which is the standalone monkey server path. The http
input plugin does not use mk_lib — it has its own connection handler, and plugins/in_http/http_conn.c only
initialises the flag:
session->close_now=MK_FALSE; /* http_conn.c:201 — set, never read */
grep -c close_now plugins/in_http/http_conn.c is 1: the initialisation. Nothing in in_http ever reads it.
Expected behavior
After sending the response for a request with Connection: close, the server should close the connection (and
should include Connection: close in the response).
Your Environment
Fluent Bit 5.1.5 (fluent/fluent-bit:latest)
Linux, aarch64, official container image
Input: http plugin, default settings
Impact
Pre-auth. Every client that uses Connection: close — the default for many one-shot HTTP clients — pays a 10 s
stall waiting for a close that only comes from the server timeout. It also holds a connection slot for those 10 s.
For accuracy: the response itself is fine — it carries content-length: 0, so the message is properly delimited and a client is not left guessing where the body ends. The defect is only the missing close (and the missing Connection: close echo), which costs the 10 s stall.
Sharper root cause than my first description, and it also explains why HTTP/1.0 behaves differently.
close_now is never set in this path. The only caller of mk_http_keepalive_check() — the function that turns the parsed header into cs->close_now = MK_TRUE — is mk_http_handler() in mk_http.c:186, which is the standalone monkey server. The http input plugin does not use mk_http_handler; it has its own handler in plugins/in_http/http_conn.c, and grep -c close_now plugins/in_http/http_conn.c is 1 — the initialisation to MK_FALSE. So for in_http the flag is always FALSE, and the if (cs->close_now == MK_TRUE) teardown in mk_http.c:1231 is never reached.
Consistent with that: an HTTP/1.0 request does close immediately (EOF at 0.00 s), because the protocol branch sets close_now before the header block, and that path is reached. HTTP/1.1 with Connection: close does not, because the flag is set by a function in_http never calls.
Activity
arygupt commentedon Oct 25, 2026
For accuracy: the response itself is fine — it carries
content-length: 0, so the message is properly delimited and a client is not left guessing where the body ends. The defect is only the missing close (and the missingConnection: closeecho), which costs the 10 s stall.arygupt commentedon Oct 25, 2026
Sharper root cause than my first description, and it also explains why HTTP/1.0 behaves differently.
close_nowis never set in this path. The only caller ofmk_http_keepalive_check()— the function that turns the parsed header intocs->close_now = MK_TRUE— ismk_http_handler()inmk_http.c:186, which is the standalone monkey server. Thehttpinput plugin does not usemk_http_handler; it has its own handler inplugins/in_http/http_conn.c, andgrep -c close_now plugins/in_http/http_conn.cis 1 — the initialisation toMK_FALSE. So forin_httpthe flag is always FALSE, and theif (cs->close_now == MK_TRUE)teardown inmk_http.c:1231is never reached.Consistent with that: an HTTP/1.0 request does close immediately (EOF at 0.00 s), because the protocol branch sets
close_nowbefore the header block, and that path is reached. HTTP/1.1 withConnection: closedoes not, because the flag is set by a functionin_httpnever calls.