diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c
index 9afa0533a6..9273984727 100644
--- a/src/interfaces/libpq/fe-misc.c
+++ b/src/interfaces/libpq/fe-misc.c
@@ -823,6 +823,10 @@ definitelyFailed:
  * Return 0 on success, -1 on failure and 1 when not all data could be sent
  * because the socket would block and the connection is non-blocking.
  *
+ * Note that this is also responsible for consuming data from the socket
+ * (putting it in conn->inBuffer) in any situation where we can't send
+ * all the specified data immediately.
+ *
  * Upon write failure, conn->write_failed is set and the error message is
  * saved in conn->write_err_msg, but we clear the output buffer and return
  * zero anyway; this is because callers should soldier on until it's possible
@@ -842,12 +846,20 @@ pqSendSome(PGconn *conn, int len)
 	 * on that connection.  Even if the kernel would let us, we've probably
 	 * lost message boundary sync with the server.  conn->write_failed
 	 * therefore persists until the connection is reset, and we just discard
-	 * all data presented to be written.
+	 * all data presented to be written.  However, as long as we still have a
+	 * valid socket, we should continue to absorb data from the backend, so
+	 * that we can collect any final error messages.
 	 */
 	if (conn->write_failed)
 	{
 		/* conn->write_err_msg should be set up already */
 		conn->outCount = 0;
+		/* Absorb input data if any, and detect socket closure */
+		if (conn->sock != PGINVALID_SOCKET)
+		{
+			if (pqReadData(conn) < 0)
+				return -1;
+		}
 		return 0;
 	}
 
@@ -917,6 +929,13 @@ pqSendSome(PGconn *conn, int len)
 
 					/* Discard queued data; no chance it'll ever be sent */
 					conn->outCount = 0;
+
+					/* Absorb input data if any, and detect socket closure */
+					if (conn->sock != PGINVALID_SOCKET)
+					{
+						if (pqReadData(conn) < 0)
+							return -1;
+					}
 					return 0;
 			}
 		}
