diff --git a/mongoose.c b/mongoose.c
index 7c4809ea99dcecdd8c373a23870f53c6447869a6..2b4061807dea9d4c104c137faa7700f65d487b65 100644
--- a/mongoose.c
+++ b/mongoose.c
@@ -498,13 +498,21 @@ static const char *status_code_to_str(int status_code) {
   }
 }
 
-static void send_http_error(struct connection *conn, int code) {
+static void send_http_error(struct connection *conn, int code,
+                            const char *fmt, ...) {
   const char *message = status_code_to_str(code);
   char headers[200], body[200];
+  va_list ap;
   int body_len, headers_len;
 
   conn->mg_conn.status_code = code;
   body_len = mg_snprintf(body, sizeof(body), "%d %s\n", code, message);
+  if (fmt != NULL) {
+    body[body_len++] = '\n';
+    va_start(ap, fmt);
+    body_len += mg_snprintf(body + body_len, sizeof(body) - body_len, fmt, ap);
+    va_end(ap);
+  }
   if (code >= 300 && code <= 399) {
     // 3xx errors do not have body
     body_len = 0;
@@ -906,7 +914,7 @@ static void open_cgi_endpoint(struct connection *conn, const char *prog) {
     conn->endpoint.cgi_sock = fds[0];
   } else {
     closesocket(fds[0]);
-    send_http_error(conn, 500);
+    send_http_error(conn, 500, "start_process(%s) failed", prog);
   }
 
   closesocket(fds[1]);
@@ -1036,7 +1044,7 @@ static struct connection *accept_new_connection(struct mg_server *server) {
 }
 
 static void close_conn(struct connection *conn) {
-  DBG(("closing %p %d %d", conn, conn->flags, conn->endpoint_type));
+  DBG(("%p %d %d", conn, conn->flags, conn->endpoint_type));
   LINKED_LIST_REMOVE(&conn->link);
   closesocket(conn->client_sock);
   free(conn->request);            // It's OK to free(NULL), ditto below
@@ -1671,7 +1679,8 @@ static void write_to_client(struct connection *conn) {
   0;
 #endif
 
-  DBG(("Written %d of %d(%d): [%.*s ...]", n, io->len, io->size, 40, io->buf));
+  DBG(("%p Written %d of %d(%d): [%.*s ...]",
+       conn, n, io->len, io->size, 40, io->buf));
 
   if (is_error(n)) {
     conn->flags |= CONN_CLOSE;
@@ -2287,7 +2296,7 @@ static void handle_mkcol(struct connection *conn, const char *path) {
   } else if (errno == ENOENT) {
     status_code = 409;
   }
-  send_http_error(conn, status_code);
+  send_http_error(conn, status_code, NULL);
 }
 
 static int remove_directory(const char *dir) {
@@ -2318,14 +2327,14 @@ static void handle_delete(struct connection *conn, const char *path) {
   file_stat_t st;
 
   if (!stat(path, &st)) {
-    send_http_error(conn, 404);
+    send_http_error(conn, 404, NULL);
   } else if (S_ISDIR(st.st_mode)) {
     remove_directory(path);
-    send_http_error(conn, 204);
+    send_http_error(conn, 204, NULL);
   } else if (!remove(path) == 0) {
-    send_http_error(conn, 204);
+    send_http_error(conn, 204, NULL);
   } else {
-    send_http_error(conn, 423);
+    send_http_error(conn, 423, NULL);
   }
 }
 
@@ -2361,12 +2370,12 @@ static void handle_put(struct connection *conn, const char *path) {
               conn->mg_conn.status_code);
     close_local_endpoint(conn);
   } else if (rc == -1) {
-    send_http_error(conn, 500);
+    send_http_error(conn, 500, "put_dir: %s", strerror(errno));
   } else if (cl_hdr == NULL) {
-    send_http_error(conn, 411);
+    send_http_error(conn, 411, NULL);
   } else if ((conn->endpoint.fd =
               open(path, O_RDWR | O_CREAT | O_TRUNC, 0644)) < 0) {
-    send_http_error(conn, 500);
+    send_http_error(conn, 500, "open(%s): %s", path, strerror(errno));
   } else {
     DBG(("PUT [%s] %d", path, conn->local_iobuf.len));
     conn->endpoint_type = EP_PUT;
@@ -3029,7 +3038,7 @@ static void handle_lsp_request(struct connection *conn, const char *path,
       (p = mmap(NULL, st->st_size, PROT_READ, MAP_PRIVATE,
                 fileno(fp), 0)) == MAP_FAILED ||
       (L = luaL_newstate()) == NULL) {
-    send_http_error(conn, 500);
+    send_http_error(conn, 500, "mmap(%s): %s", path, strerror(errno));
   } else {
     // We're not sending HTTP headers here, Lua page must do it.
     prepare_lua_environment(&conn->mg_conn, L);
@@ -3066,7 +3075,8 @@ static void open_local_endpoint(struct connection *conn) {
       const char *cl = mg_get_header(&conn->mg_conn, "Content-Length");
       if (!strcmp(conn->mg_conn.request_method, "POST") &&
           (cl == NULL || to64(cl) > USE_POST_SIZE_LIMIT)) {
-        send_http_error(conn, 500);
+        send_http_error(conn, 500, "POST size > %zu",
+                        (size_t) USE_POST_SIZE_LIMIT);
       }
     }
 #endif
@@ -3079,7 +3089,7 @@ static void open_local_endpoint(struct connection *conn) {
   if (!strcmp(conn->mg_conn.request_method, "OPTIONS")) {
     send_options(conn);
   } else if (conn->server->config_options[DOCUMENT_ROOT] == NULL) {
-    send_http_error(conn, 404);
+    send_http_error(conn, 404, NULL);
 #ifndef NO_AUTH
   } else if ((!is_dangerous_dav_request(conn) && !is_authorized(conn, path)) ||
              (is_dangerous_dav_request(conn) && !is_authorized_for_dav(conn))) {
@@ -3096,7 +3106,7 @@ static void open_local_endpoint(struct connection *conn) {
     handle_put(conn, path);
 #endif
   } else if (!exists || must_hide_file(conn, path)) {
-    send_http_error(conn, 404);
+    send_http_error(conn, 404, NULL);
   } else if (is_directory &&
              conn->mg_conn.uri[strlen(conn->mg_conn.uri) - 1] != '/') {
     conn->mg_conn.status_code = 301;
@@ -3108,37 +3118,37 @@ static void open_local_endpoint(struct connection *conn) {
 #ifndef NO_DIRECTORY_LISTING
       send_directory_listing(conn, path);
 #else
-      send_http_error(conn, 501);
+      send_http_error(conn, 501, NULL);
 #endif
     } else {
-      send_http_error(conn, 403);
+      send_http_error(conn, 403, NULL);
     }
   } else if (match_prefix(lua_pat, sizeof(lua_pat) - 1, path) > 0) {
 #ifdef USE_LUA
     handle_lsp_request(conn, path, &st);
 #else
-    send_http_error(conn, 501);
+    send_http_error(conn, 501, NULL);
 #endif
   } else if (match_prefix(cgi_pat, strlen(cgi_pat), path) > 0) {
     if (strcmp(conn->mg_conn.request_method, "POST") &&
         strcmp(conn->mg_conn.request_method, "HEAD") &&
         strcmp(conn->mg_conn.request_method, "GET")) {
-      send_http_error(conn, 501);
+      send_http_error(conn, 501, NULL);
     } else {
 #if !defined(NO_CGI)
       open_cgi_endpoint(conn, path);
 #else
-      send_http_error(conn, 501);
+      send_http_error(conn, 501, NULL);
 #endif // !NO_CGI
     }
   } else if (is_not_modified(conn, &st)) {
-    send_http_error(conn, 304);
+    send_http_error(conn, 304, NULL);
   } else if ((conn->endpoint.fd = open(path, O_RDONLY | O_BINARY)) != -1) {
     // O_BINARY is required for Windows, otherwise in default text mode
     // two bytes \r\n will be read as one.
     open_file_endpoint(conn, path, &st);
   } else {
-    send_http_error(conn, 404);
+    send_http_error(conn, 404, NULL);
   }
 }
 
@@ -3176,23 +3186,23 @@ static void process_request(struct connection *conn) {
     // become invalid.
     conn->request = (char *) malloc(conn->request_len);
     memcpy(conn->request, io->buf, conn->request_len);
-    DBG(("==> [%.*s]", conn->request_len, conn->request));
+    DBG(("%p ==> [%.*s]", conn, conn->request_len, conn->request));
     memmove(io->buf, io->buf + conn->request_len, io->len - conn->request_len);
     io->len -= conn->request_len;
     conn->request_len = parse_http_message(conn->request, conn->request_len,
                                            &conn->mg_conn);
   }
 
-  DBG(("%d %d", conn->request_len, io->len));
+  DBG(("%p %d %d", conn, conn->request_len, io->len));
   if (conn->request_len < 0 ||
       (conn->request_len > 0 && !is_valid_uri(conn->mg_conn.uri))) {
-    send_http_error(conn, 400);
+    send_http_error(conn, 400, NULL);
   } else if (conn->request_len == 0 && io->len > MAX_REQUEST_SIZE) {
-    send_http_error(conn, 413);
+    send_http_error(conn, 413, NULL);
   } else if (conn->request_len > 0 &&
              strcmp(conn->mg_conn.http_version, "1.0") != 0 &&
              strcmp(conn->mg_conn.http_version, "1.1") != 0) {
-    send_http_error(conn, 505);
+    send_http_error(conn, 505, NULL);
   } else if (conn->request_len > 0 && conn->endpoint_type == EP_NONE) {
 #ifndef NO_WEBSOCKET
     send_websocket_handshake_if_requested(&conn->mg_conn);
@@ -3234,6 +3244,7 @@ static void read_from_client(struct connection *conn) {
     n = recv(conn->client_sock, buf, sizeof(buf), 0);
   }
 
+  DBG(("%p %d", conn, n));
   if (is_error(n)) {
     conn->flags |= CONN_CLOSE;
   } else if (n > 0) {
@@ -3246,7 +3257,7 @@ static void read_from_cgi(struct connection *conn) {
   char buf[IOBUF_SIZE];
   int len, n = recv(conn->endpoint.cgi_sock, buf, sizeof(buf), 0);
 
-  DBG(("-> %d", n));
+  DBG(("%p %d", conn, n));
   if (is_error(n)) {
     close_local_endpoint(conn);
   } else if (n > 0) {