diff --git a/src/lib/proxy.c b/src/lib/proxy.c
index 3876e7a..6d480b8 100644
--- a/src/lib/proxy.c
+++ b/src/lib/proxy.c
@@ -139,9 +139,10 @@ proxy_ctx_t *proxy_get_by_conf(host_config_t *conf) {
 
 void proxy_unlock_ctx(proxy_ctx_t *ctx) {
     int n = (int) ((ctx - proxies) / MAX_PROXY_CNX_PER_HOST);
+    int was_in_use = ctx->in_use;
     ctx->in_use = 0;
     ctx->client = NULL;
-    sem_post(&available[n]);
+    if (was_in_use) sem_post(&available[n]);
 }
 
 int proxy_request_header(http_req *req, sock *sock) {
@@ -340,6 +341,7 @@ static int proxy_connect(proxy_ctx_t *proxy, host_config_t *conf, http_res *res,
         if ((ret = SSL_do_handshake(proxy->proxy.ssl)) != 1) {
             sock_error(&proxy->proxy, (int) ret);
             SSL_free(proxy->proxy.ssl);
+            proxy->proxy.ssl = NULL;
             res->status = http_get_status(502);
             ctx->origin = SERVER_REQ;
             error("Unable to perform handshake");
diff --git a/src/worker/proxy_handler.c b/src/worker/proxy_handler.c
index 79f6883..b136e92 100644
--- a/src/worker/proxy_handler.c
+++ b/src/worker/proxy_handler.c
@@ -28,22 +28,22 @@ void proxy_handler_func(client_ctx_t *ctx) {
 
     if (ret == 1) {
         proxy_unlock_ctx(ctx->proxy);
-        ctx->proxy = NULL;
     } else if (ctx->use_proxy == 0) {
         proxy_close(ctx->proxy);
+        proxy_unlock_ctx(ctx->proxy);
     } else if (ctx->use_proxy == 1) {
         if (proxy_handler_2(ctx) == 1) {
             // chunked
             return;
         }
         proxy_unlock_ctx(ctx->proxy);
-        ctx->proxy = NULL;
     } else if (ctx->use_proxy == 2) {
         // WebSocket
         ws_handle_connection(ctx);
         return;
     }
 
+    ctx->proxy = NULL;
     request_complete(ctx);
     handle_request(ctx);
 }
@@ -61,6 +61,9 @@ static int proxy_handler_1(client_ctx_t *ctx) {
     ctx->use_proxy = proxy_init(&ctx->proxy, &ctx->req, res, status, ctx->conf, &ctx->socket, &ctx->custom_status, ctx->err_msg) == 0;
     ctx->proxy->client = ctx;
 
+    if (ctx->use_proxy == 0)
+        return 0;
+
     if (res->status->code == 101) {
         const char *connection = http_get_header_field(&res->hdr, "Connection");
         const char *upgrade = http_get_header_field(&res->hdr, "Upgrade");
@@ -110,15 +113,20 @@ static int proxy_handler_1(client_ctx_t *ctx) {
 
 static void proxy_chunk_next_cb(chunk_ctx_t *ctx) {
     proxy_unlock_ctx(ctx->client->proxy);
-    ctx->client->proxy = NULL;
 
+    ctx->client->proxy = NULL;
     request_complete(ctx->client);
     handle_request(ctx->client);
 }
 
 static void proxy_chunk_err_cb(chunk_ctx_t *ctx) {
     ctx->client->c_keep_alive = 0;
-    proxy_chunk_next_cb(ctx);
+    proxy_close(ctx->client->proxy);
+    proxy_unlock_ctx(ctx->client->proxy);
+
+    ctx->client->proxy = NULL;
+    request_complete(ctx->client);
+    handle_request(ctx->client);
 }
 
 static int proxy_handler_2(client_ctx_t *ctx) {