diff --git a/lib/output.c b/lib/output.c
index 977d1de45d300fe877eec30181fff6bb7c3c6b87..44b2ab7e13c6b3819cae9b3201ecc4566735865d 100644
--- a/lib/output.c
+++ b/lib/output.c
@@ -270,7 +270,9 @@ LWS_VISIBLE int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf,
 
 	/* websocket protocol, either binary or text */
 
-	if (wsi->state != WSI_STATE_ESTABLISHED)
+	if (wsi->state != WSI_STATE_ESTABLISHED &&
+	    !(wsi->state == WSI_STATE_RETURNED_CLOSE_ALREADY &&
+	      protocol == LWS_WRITE_CLOSE))
 		return -1;
 
 	/* if we are continuing a frame that already had its header done */
diff --git a/lib/service.c b/lib/service.c
index 1571a198fbf91886e46306a12fea0ed7aa0c8735..32e09025dd0408fb7aa0178984bb31b1acfff97c 100644
--- a/lib/service.c
+++ b/lib/service.c
@@ -93,8 +93,10 @@ lws_handle_POLLOUT_event(struct libwebsocket_context *context,
 #endif
 	/* pending control packets have next priority */
 	
-	if (wsi->state == WSI_STATE_ESTABLISHED &&
-	    wsi->u.ws.ping_pending_flag) {
+	if ((wsi->state == WSI_STATE_ESTABLISHED &&
+	     wsi->u.ws.ping_pending_flag) ||
+	    (wsi->state == WSI_STATE_RETURNED_CLOSE_ALREADY &&
+	     wsi->u.ws.payload_is_close)) {
 
 		if (wsi->u.ws.payload_is_close)
 			write_type = LWS_WRITE_CLOSE;