diff --git a/src/interfaces/libpq/fe-protocol2.c b/src/interfaces/libpq/fe-protocol2.c
index eeba7f35047089d849864f18ee4db5f5a348ca26..9ff73dbd58b22689d2ec2443385ab733e9493743 100644
--- a/src/interfaces/libpq/fe-protocol2.c
+++ b/src/interfaces/libpq/fe-protocol2.c
@@ -498,10 +498,17 @@ pqParseInput2(PGconn *conn)
 						conn->result = PQmakeEmptyPGresult(conn,
 														   PGRES_COMMAND_OK);
 						if (!conn->result)
-							return;
+						{
+							printfPQExpBuffer(&conn->errorMessage,
+											  libpq_gettext("out of memory"));
+							pqSaveErrorResult(conn);
+						}
+					}
+					if (conn->result)
+					{
+						strlcpy(conn->result->cmdStatus, conn->workBuffer.data,
+								CMDSTATUS_LEN);
 					}
-					strlcpy(conn->result->cmdStatus, conn->workBuffer.data,
-							CMDSTATUS_LEN);
 					checkXactStatus(conn, conn->workBuffer.data);
 					conn->asyncStatus = PGASYNC_READY;
 					break;
@@ -522,8 +529,16 @@ pqParseInput2(PGconn *conn)
 										 "unexpected character %c following empty query response (\"I\" message)",
 										 id);
 					if (conn->result == NULL)
+					{
 						conn->result = PQmakeEmptyPGresult(conn,
 														   PGRES_EMPTY_QUERY);
+						if (!conn->result)
+						{
+							printfPQExpBuffer(&conn->errorMessage,
+											  libpq_gettext("out of memory"));
+							pqSaveErrorResult(conn);
+						}
+					}
 					conn->asyncStatus = PGASYNC_READY;
 					break;
 				case 'K':		/* secret key data from the backend */
@@ -965,14 +980,17 @@ pqGetErrorNotice2(PGconn *conn, bool isError)
 	 * Make a PGresult to hold the message.  We temporarily lie about the
 	 * result status, so that PQmakeEmptyPGresult doesn't uselessly copy
 	 * conn->errorMessage.
+	 *
+	 * NB: This allocation can fail, if you run out of memory. The rest of the
+	 * function handles that gracefully, and we still try to set the error
+	 * message as the connection's error message.
 	 */
 	res = PQmakeEmptyPGresult(conn, PGRES_EMPTY_QUERY);
-	if (!res)
-		goto failure;
-	res->resultStatus = isError ? PGRES_FATAL_ERROR : PGRES_NONFATAL_ERROR;
-	res->errMsg = pqResultStrdup(res, workBuf.data);
-	if (!res->errMsg)
-		goto failure;
+	if (res)
+	{
+		res->resultStatus = isError ? PGRES_FATAL_ERROR : PGRES_NONFATAL_ERROR;
+		res->errMsg = pqResultStrdup(res, workBuf.data);
+	}
 
 	/*
 	 * Break the message into fields.  We can't do very much here, but we can
@@ -1024,15 +1042,22 @@ pqGetErrorNotice2(PGconn *conn, bool isError)
 		pqClearAsyncResult(conn);
 		conn->result = res;
 		resetPQExpBuffer(&conn->errorMessage);
-		appendPQExpBufferStr(&conn->errorMessage, res->errMsg);
+		if (res && !PQExpBufferDataBroken(workBuf) && res->errMsg)
+			appendPQExpBufferStr(&conn->errorMessage, res->errMsg);
+		else
+			printfPQExpBuffer(&conn->errorMessage,
+							  libpq_gettext("out of memory"));
 		if (conn->xactStatus == PQTRANS_INTRANS)
 			conn->xactStatus = PQTRANS_INERROR;
 	}
 	else
 	{
-		if (res->noticeHooks.noticeRec != NULL)
-			(*res->noticeHooks.noticeRec) (res->noticeHooks.noticeRecArg, res);
-		PQclear(res);
+		if (res)
+		{
+			if (res->noticeHooks.noticeRec != NULL)
+				(*res->noticeHooks.noticeRec) (res->noticeHooks.noticeRecArg, res);
+			PQclear(res);
+		}
 	}
 
 	termPQExpBuffer(&workBuf);
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index a847f084fa0e8dc6ffc8a4228cacf9e3e76dbf51..dbc0d89a4ed04b1a935005814360784bdf829106 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -204,10 +204,15 @@ pqParseInput3(PGconn *conn)
 						conn->result = PQmakeEmptyPGresult(conn,
 														   PGRES_COMMAND_OK);
 						if (!conn->result)
-							return;
+						{
+							printfPQExpBuffer(&conn->errorMessage,
+											  libpq_gettext("out of memory"));
+							pqSaveErrorResult(conn);
+						}
 					}
-					strlcpy(conn->result->cmdStatus, conn->workBuffer.data,
-							CMDSTATUS_LEN);
+					if (conn->result)
+						strlcpy(conn->result->cmdStatus, conn->workBuffer.data,
+								CMDSTATUS_LEN);
 					conn->asyncStatus = PGASYNC_READY;
 					break;
 				case 'E':		/* error return */
@@ -226,7 +231,11 @@ pqParseInput3(PGconn *conn)
 						conn->result = PQmakeEmptyPGresult(conn,
 														   PGRES_EMPTY_QUERY);
 						if (!conn->result)
-							return;
+						{
+							printfPQExpBuffer(&conn->errorMessage,
+											  libpq_gettext("out of memory"));
+							pqSaveErrorResult(conn);
+						}
 					}
 					conn->asyncStatus = PGASYNC_READY;
 					break;
@@ -239,7 +248,11 @@ pqParseInput3(PGconn *conn)
 							conn->result = PQmakeEmptyPGresult(conn,
 														   PGRES_COMMAND_OK);
 							if (!conn->result)
-								return;
+							{
+								printfPQExpBuffer(&conn->errorMessage,
+												  libpq_gettext("out of memory"));
+								pqSaveErrorResult(conn);
+							}
 						}
 						conn->asyncStatus = PGASYNC_READY;
 					}
@@ -306,7 +319,11 @@ pqParseInput3(PGconn *conn)
 							conn->result = PQmakeEmptyPGresult(conn,
 														   PGRES_COMMAND_OK);
 							if (!conn->result)
-								return;
+							{
+								printfPQExpBuffer(&conn->errorMessage,
+												  libpq_gettext("out of memory"));
+								pqSaveErrorResult(conn);
+							}
 						}
 						conn->asyncStatus = PGASYNC_READY;
 					}
@@ -822,11 +839,14 @@ pqGetErrorNotice3(PGconn *conn, bool isError)
 	 * Make a PGresult to hold the accumulated fields.  We temporarily lie
 	 * about the result status, so that PQmakeEmptyPGresult doesn't uselessly
 	 * copy conn->errorMessage.
+	 *
+	 * NB: This allocation can fail, if you run out of memory. The rest of the
+	 * function handles that gracefully, and we still try to set the error
+	 * message as the connection's error message.
 	 */
 	res = PQmakeEmptyPGresult(conn, PGRES_EMPTY_QUERY);
-	if (!res)
-		goto fail;
-	res->resultStatus = isError ? PGRES_FATAL_ERROR : PGRES_NONFATAL_ERROR;
+	if (res)
+		res->resultStatus = isError ? PGRES_FATAL_ERROR : PGRES_NONFATAL_ERROR;
 
 	/*
 	 * Read the fields and save into res.
@@ -966,20 +986,27 @@ pqGetErrorNotice3(PGconn *conn, bool isError)
 	 */
 	if (isError)
 	{
-		res->errMsg = pqResultStrdup(res, workBuf.data);
-		if (!res->errMsg)
-			goto fail;
+		if (res)
+			res->errMsg = pqResultStrdup(res, workBuf.data);
 		pqClearAsyncResult(conn);
 		conn->result = res;
-		appendPQExpBufferStr(&conn->errorMessage, workBuf.data);
+		if (PQExpBufferDataBroken(workBuf))
+			printfPQExpBuffer(&conn->errorMessage,
+							  libpq_gettext("out of memory"));
+		else
+			appendPQExpBufferStr(&conn->errorMessage, workBuf.data);
 	}
 	else
 	{
-		/* We can cheat a little here and not copy the message. */
-		res->errMsg = workBuf.data;
-		if (res->noticeHooks.noticeRec != NULL)
-			(*res->noticeHooks.noticeRec) (res->noticeHooks.noticeRecArg, res);
-		PQclear(res);
+		/* if we couldn't allocate the result set, just discard the NOTICE */
+		if (res)
+		{
+			/* We can cheat a little here and not copy the message. */
+			res->errMsg = workBuf.data;
+			if (res->noticeHooks.noticeRec != NULL)
+				(*res->noticeHooks.noticeRec) (res->noticeHooks.noticeRecArg, res);
+			PQclear(res);
+		}
 	}
 
 	termPQExpBuffer(&workBuf);