diff --git a/src/httpc.c b/src/httpc.c
index 950f8b32f6b54c8dfab72ce36965ba8c71bb9d06..e9f703ba1b9c036af7c9cd856b4c7f33bfdb9281 100644
--- a/src/httpc.c
+++ b/src/httpc.c
@@ -37,6 +37,8 @@
 #include "fiber.h"
 #include "errinj.h"
 
+#define MAX_HEADER_LEN 8192
+
 /**
  * libcurl callback for CURLOPT_WRITEFUNCTION
  * @see https://curl.haxx.se/libcurl/c/CURLOPT_WRITEFUNCTION.html
@@ -173,9 +175,14 @@ httpc_request_delete(struct httpc_request *req)
 int
 httpc_set_header(struct httpc_request *req, const char *fmt, ...)
 {
+	static __thread char header[MAX_HEADER_LEN + 1];
 	va_list ap;
 	va_start(ap, fmt);
-	const char *header = tt_vsprintf(fmt, ap);
+	int rc = vsnprintf(header, MAX_HEADER_LEN + 1, fmt, ap);
+	if (rc > MAX_HEADER_LEN) {
+		diag_set(IllegalParams, "header is too large");
+		return -1;
+	}
 	va_end(ap);
 
 	struct curl_slist *l = curl_slist_append(req->headers, header);
diff --git a/test/app-tap/http_client.test.lua b/test/app-tap/http_client.test.lua
index 10a3728f8713f61e37b02afb9ca7565e94af30df..6a4ec91773e89f059388cfde6d5b1fc2f888bac6 100755
--- a/test/app-tap/http_client.test.lua
+++ b/test/app-tap/http_client.test.lua
@@ -206,7 +206,7 @@ local function test_errors(test)
 end
 
 local function test_headers(test, url, opts)
-    test:plan(19)
+    test:plan(21)
     local http = client:new()
     local r = http:get(url .. 'headers', opts)
     test:is(type(r.headers["set-cookie"]), 'string', "set-cookie check")
@@ -231,6 +231,25 @@ local function test_headers(test, url, opts)
     local r = http:get(url .. 'headers', opts)
     test:is(r.headers["very_very_very_long_headers_name1"], "true", "truncated max_header_name_length")
     opts["max_header_name_length"] = nil
+
+    -- Send large headers.
+    local MAX_HEADER_NAME = 8192
+    local hname = 'largeheader'
+
+    -- "${hname}: ${hvalue}" is 8192 bytes length
+    local hvalue = string.rep('x', MAX_HEADER_NAME - hname:len() - 2)
+    local headers = {[hname] = hvalue}
+    local r = http:post(url, nil, merge(opts, {headers = headers}))
+    test:is(r.headers[hname], hvalue, '8192 bytes header: success')
+
+    -- "${hname}: ${hvalue}" is 8193 bytes length
+    local exp_err = 'header is too large'
+    local hvalue = string.rep('x', MAX_HEADER_NAME - hname:len() - 1)
+    local headers = {[hname] = hvalue}
+    local ok, err = pcall(http.post, http, url, nil,
+                          merge(opts, {headers = headers}))
+    test:is_deeply({ok, tostring(err)}, {false, exp_err},
+                   '8193 KiB header: error')
 end
 
 local function test_special_methods(test, url, opts)