diff --git a/src/interfaces/libpq/fe-auth-scram.c b/src/interfaces/libpq/fe-auth-scram.c
index 1d9c937..e7110d5 100644
--- a/src/interfaces/libpq/fe-auth-scram.c
+++ b/src/interfaces/libpq/fe-auth-scram.c
@@ -185,14 +185,14 @@ pg_fe_scram_exchange(void *opaq, char *input, int inputlen,
 	{
 		if (inputlen == 0)
 		{
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("malformed SCRAM message (empty message)\n"));
+			appendPQExpBufferStr(&conn->errorMessage,
+								 libpq_gettext("malformed SCRAM message (empty message)\n"));
 			goto error;
 		}
 		if (inputlen != strlen(input))
 		{
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("malformed SCRAM message (length mismatch)\n"));
+			appendPQExpBufferStr(&conn->errorMessage,
+								 libpq_gettext("malformed SCRAM message (length mismatch)\n"));
 			goto error;
 		}
 	}
@@ -240,17 +240,17 @@ pg_fe_scram_exchange(void *opaq, char *input, int inputlen,
 			else
 			{
 				*success = false;
-				printfPQExpBuffer(&conn->errorMessage,
-								  libpq_gettext("incorrect server signature\n"));
+				appendPQExpBufferStr(&conn->errorMessage,
+									 libpq_gettext("incorrect server signature\n"));
 			}
 			*done = true;
 			state->state = FE_SCRAM_FINISHED;
 			break;
 
 		default:
-			/* shouldn't happen */
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("invalid SCRAM exchange state\n"));
+			/* shouldn't happen, so we don't translate the msg */
+			appendPQExpBufferStr(&conn->errorMessage,
+								 "invalid SCRAM exchange state\n");
 			goto error;
 	}
 	return;
@@ -272,7 +272,7 @@ read_attr_value(char **input, char attr, PQExpBuffer errorMessage)
 
 	if (*begin != attr)
 	{
-		printfPQExpBuffer(errorMessage,
+		appendPQExpBuffer(errorMessage,
 						  libpq_gettext("malformed SCRAM message (attribute \"%c\" expected)\n"),
 						  attr);
 		return NULL;
@@ -281,7 +281,7 @@ read_attr_value(char **input, char attr, PQExpBuffer errorMessage)
 
 	if (*begin != '=')
 	{
-		printfPQExpBuffer(errorMessage,
+		appendPQExpBuffer(errorMessage,
 						  libpq_gettext("malformed SCRAM message (expected character \"=\" for attribute \"%c\")\n"),
 						  attr);
 		return NULL;
@@ -322,16 +322,15 @@ build_client_first_message(fe_scram_state *state)
 	 */
 	if (!pg_frontend_random(raw_nonce, SCRAM_RAW_NONCE_LEN))
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("could not generate nonce\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("could not generate nonce\n"));
 		return NULL;
 	}
 
 	state->client_nonce = malloc(pg_b64_enc_len(SCRAM_RAW_NONCE_LEN) + 1);
 	if (state->client_nonce == NULL)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("out of memory\n"));
+		pqReportOOM(conn);
 		return NULL;
 	}
 	encoded_len = pg_b64_encode(raw_nonce, SCRAM_RAW_NONCE_LEN, state->client_nonce);
@@ -397,8 +396,7 @@ build_client_first_message(fe_scram_state *state)
 
 oom_error:
 	termPQExpBuffer(&buf);
-	printfPQExpBuffer(&conn->errorMessage,
-					  libpq_gettext("out of memory\n"));
+	pqReportOOM(conn);
 	return NULL;
 }
 
@@ -471,13 +469,13 @@ build_client_final_message(fe_scram_state *state)
 #else
 		/*
 		 * Chose channel binding, but the SSL library doesn't support it.
-		 * Shouldn't happen.
+		 * Shouldn't happen, so we don't translate the msg.
 		 */
 		termPQExpBuffer(&buf);
-		printfPQExpBuffer(&conn->errorMessage,
-						  "channel binding not supported by this build\n");
+		appendPQExpBufferStr(&conn->errorMessage,
+							 "channel binding not supported by this build\n");
 		return NULL;
-#endif	/* HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH */
+#endif							/* HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH */
 	}
 #ifdef HAVE_PGTLS_GET_PEER_CERTIFICATE_HASH
 	else if (conn->ssl_in_use)
@@ -519,8 +517,7 @@ build_client_final_message(fe_scram_state *state)
 
 oom_error:
 	termPQExpBuffer(&buf);
-	printfPQExpBuffer(&conn->errorMessage,
-					  libpq_gettext("out of memory\n"));
+	pqReportOOM(conn);
 	return NULL;
 }
 
@@ -539,8 +536,7 @@ read_server_first_message(fe_scram_state *state, char *input)
 	state->server_first_message = strdup(input);
 	if (state->server_first_message == NULL)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("out of memory\n"));
+		pqReportOOM(conn);
 		return false;
 	}
 
@@ -557,16 +553,15 @@ read_server_first_message(fe_scram_state *state, char *input)
 	if (strlen(nonce) < strlen(state->client_nonce) ||
 		memcmp(nonce, state->client_nonce, strlen(state->client_nonce)) != 0)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("invalid SCRAM response (nonce mismatch)\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("invalid SCRAM response (nonce mismatch)\n"));
 		return false;
 	}
 
 	state->nonce = strdup(nonce);
 	if (state->nonce == NULL)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("out of memory\n"));
+		pqReportOOM(conn);
 		return false;
 	}
 
@@ -579,8 +574,7 @@ read_server_first_message(fe_scram_state *state, char *input)
 	state->salt = malloc(pg_b64_dec_len(strlen(encoded_salt)));
 	if (state->salt == NULL)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("out of memory\n"));
+		pqReportOOM(conn);
 		return false;
 	}
 	state->saltlen = pg_b64_decode(encoded_salt,
@@ -596,14 +590,14 @@ read_server_first_message(fe_scram_state *state, char *input)
 	state->iterations = strtol(iterations_str, &endptr, 10);
 	if (*endptr != '\0' || state->iterations < 1)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("malformed SCRAM message (invalid iteration count)\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("malformed SCRAM message (invalid iteration count)\n"));
 		return false;
 	}
 
 	if (*input != '\0')
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("malformed SCRAM message (garbage at end of server-first-message)\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("malformed SCRAM message (garbage at end of server-first-message)\n"));
 
 	return true;
 }
@@ -621,8 +615,7 @@ read_server_final_message(fe_scram_state *state, char *input)
 	state->server_final_message = strdup(input);
 	if (!state->server_final_message)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("out of memory\n"));
+		pqReportOOM(conn);
 		return false;
 	}
 
@@ -632,7 +625,7 @@ read_server_final_message(fe_scram_state *state, char *input)
 		char	   *errmsg = read_attr_value(&input, 'e',
 											 &conn->errorMessage);
 
-		printfPQExpBuffer(&conn->errorMessage,
+		appendPQExpBuffer(&conn->errorMessage,
 						  libpq_gettext("error received from server in SCRAM exchange: %s\n"),
 						  errmsg);
 		return false;
@@ -648,16 +641,16 @@ read_server_final_message(fe_scram_state *state, char *input)
 	}
 
 	if (*input != '\0')
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("malformed SCRAM message (garbage at end of server-final-message)\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("malformed SCRAM message (garbage at end of server-final-message)\n"));
 
 	server_signature_len = pg_b64_decode(encoded_server_signature,
 										 strlen(encoded_server_signature),
 										 state->ServerSignature);
 	if (server_signature_len != SCRAM_KEY_LEN)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("malformed SCRAM message (invalid server signature)\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("malformed SCRAM message (invalid server signature)\n"));
 		return false;
 	}
 
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
index 540aba9..69f2efb 100644
--- a/src/interfaces/libpq/fe-auth.c
+++ b/src/interfaces/libpq/fe-auth.c
@@ -81,14 +81,12 @@ pg_GSS_error_int(PQExpBuffer str, const char *mprefix,
 }
 
 /*
- * GSSAPI errors contain two parts; put both into conn->errorMessage.
+ * GSSAPI errors contain two parts; append both to conn->errorMessage.
  */
 static void
 pg_GSS_error(const char *mprefix, PGconn *conn,
 			 OM_uint32 maj_stat, OM_uint32 min_stat)
 {
-	resetPQExpBuffer(&conn->errorMessage);
-
 	/* Fetch major error codes */
 	pg_GSS_error_int(&conn->errorMessage, mprefix, maj_stat, GSS_C_GSS_CODE);
 
@@ -118,9 +116,7 @@ pg_GSS_continue(PGconn *conn, int payloadlen)
 		ginbuf.value = malloc(payloadlen);
 		if (!ginbuf.value)
 		{
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("out of memory allocating GSSAPI buffer (%d)\n"),
-							  payloadlen);
+			pqReportOOM(conn);
 			return STATUS_ERROR;
 		}
 		if (pqGetnchar(ginbuf.value, payloadlen, conn))
@@ -203,15 +199,15 @@ pg_GSS_startup(PGconn *conn, int payloadlen)
 
 	if (!(host && host[0] != '\0'))
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("host name must be specified\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("host name must be specified\n"));
 		return STATUS_ERROR;
 	}
 
 	if (conn->gctx)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("duplicate GSS authentication request\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("duplicate GSS authentication request\n"));
 		return STATUS_ERROR;
 	}
 
@@ -223,8 +219,7 @@ pg_GSS_startup(PGconn *conn, int payloadlen)
 	temp_gbuf.value = (char *) malloc(maxlen);
 	if (!temp_gbuf.value)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("out of memory\n"));
+		pqReportOOM(conn);
 		return STATUS_ERROR;
 	}
 	snprintf(temp_gbuf.value, maxlen, "%s@%s",
@@ -268,10 +263,10 @@ pg_SSPI_error(PGconn *conn, const char *mprefix, SECURITY_STATUS r)
 					  FORMAT_MESSAGE_FROM_SYSTEM,
 					  NULL, r, 0,
 					  sysmsg, sizeof(sysmsg), NULL) == 0)
-		printfPQExpBuffer(&conn->errorMessage, "%s: SSPI error %x\n",
+		appendPQExpBuffer(&conn->errorMessage, "%s: SSPI error %x\n",
 						  mprefix, (unsigned int) r);
 	else
-		printfPQExpBuffer(&conn->errorMessage, "%s: %s (%x)\n",
+		appendPQExpBuffer(&conn->errorMessage, "%s: %s (%x)\n",
 						  mprefix, sysmsg, (unsigned int) r);
 }
 
@@ -299,9 +294,7 @@ pg_SSPI_continue(PGconn *conn, int payloadlen)
 		inputbuf = malloc(payloadlen);
 		if (!inputbuf)
 		{
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("out of memory allocating SSPI buffer (%d)\n"),
-							  payloadlen);
+			pqReportOOM(conn);
 			return STATUS_ERROR;
 		}
 		if (pqGetnchar(inputbuf, payloadlen, conn))
@@ -359,7 +352,7 @@ pg_SSPI_continue(PGconn *conn, int payloadlen)
 		conn->sspictx = malloc(sizeof(CtxtHandle));
 		if (conn->sspictx == NULL)
 		{
-			printfPQExpBuffer(&conn->errorMessage, libpq_gettext("out of memory\n"));
+			pqReportOOM(conn);
 			return STATUS_ERROR;
 		}
 		memcpy(conn->sspictx, &newContext, sizeof(CtxtHandle));
@@ -376,9 +369,11 @@ pg_SSPI_continue(PGconn *conn, int payloadlen)
 			/*
 			 * This should never happen, at least not for Kerberos
 			 * authentication. Keep check in case it shows up with other
-			 * authentication methods later.
+			 * authentication methods later.  We intentionally don't translate
+			 * the message, since we aren't expecting it to happen.
 			 */
-			printfPQExpBuffer(&conn->errorMessage, "SSPI returned invalid number of output buffers\n");
+			appendPQExpBufferStr(&conn->errorMessage,
+								 "SSPI returned invalid number of output buffers\n");
 			return STATUS_ERROR;
 		}
 
@@ -418,8 +413,8 @@ pg_SSPI_startup(PGconn *conn, int use_negotiate, int payloadlen)
 
 	if (conn->sspictx)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("duplicate SSPI authentication request\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("duplicate SSPI authentication request\n"));
 		return STATUS_ERROR;
 	}
 
@@ -429,7 +424,7 @@ pg_SSPI_startup(PGconn *conn, int use_negotiate, int payloadlen)
 	conn->sspicred = malloc(sizeof(CredHandle));
 	if (conn->sspicred == NULL)
 	{
-		printfPQExpBuffer(&conn->errorMessage, libpq_gettext("out of memory\n"));
+		pqReportOOM(conn);
 		return STATUS_ERROR;
 	}
 
@@ -457,14 +452,14 @@ pg_SSPI_startup(PGconn *conn, int use_negotiate, int payloadlen)
 	 */
 	if (!(host && host[0] != '\0'))
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("host name must be specified\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("host name must be specified\n"));
 		return STATUS_ERROR;
 	}
 	conn->sspitarget = malloc(strlen(conn->krbsrvname) + strlen(host) + 2);
 	if (!conn->sspitarget)
 	{
-		printfPQExpBuffer(&conn->errorMessage, libpq_gettext("out of memory\n"));
+		pqReportOOM(conn);
 		return STATUS_ERROR;
 	}
 	sprintf(conn->sspitarget, "%s/%s", conn->krbsrvname, host);
@@ -497,8 +492,8 @@ pg_SASL_init(PGconn *conn, int payloadlen)
 
 	if (conn->sasl_state)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("duplicate SASL authentication request\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("duplicate SASL authentication request\n"));
 		goto error;
 	}
 
@@ -513,8 +508,8 @@ pg_SASL_init(PGconn *conn, int payloadlen)
 	{
 		if (pqGets(&mechanism_buf, conn))
 		{
-			printfPQExpBuffer(&conn->errorMessage,
-							  "fe_sendauth: invalid authentication request from server: invalid list of authentication mechanisms\n");
+			appendPQExpBufferStr(&conn->errorMessage,
+								 libpq_gettext("invalid authentication request from server: invalid list of authentication mechanisms\n"));
 			goto error;
 		}
 		if (PQExpBufferDataBroken(mechanism_buf))
@@ -545,8 +540,8 @@ pg_SASL_init(PGconn *conn, int payloadlen)
 				 * the client and server supported it. The SCRAM exchange
 				 * checks for that, to prevent downgrade attacks.
 				 */
-				printfPQExpBuffer(&conn->errorMessage,
-								  libpq_gettext("server offered SCRAM-SHA-256-PLUS authentication over a non-SSL connection\n"));
+				appendPQExpBufferStr(&conn->errorMessage,
+									 libpq_gettext("server offered SCRAM-SHA-256-PLUS authentication over a non-SSL connection\n"));
 				goto error;
 			}
 		}
@@ -557,8 +552,8 @@ pg_SASL_init(PGconn *conn, int payloadlen)
 
 	if (!selected_mechanism)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("none of the server's SASL authentication mechanisms are supported\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("none of the server's SASL authentication mechanisms are supported\n"));
 		goto error;
 	}
 
@@ -578,8 +573,9 @@ pg_SASL_init(PGconn *conn, int payloadlen)
 		password = conn->pgpass;
 	if (password == NULL || password[0] == '\0')
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  PQnoPasswordSupplied);
+		/* Intentionally not translated. */
+		appendPQExpBufferStr(&conn->errorMessage,
+							 PQnoPasswordSupplied);
 		goto error;
 	}
 
@@ -639,8 +635,7 @@ oom_error:
 	termPQExpBuffer(&mechanism_buf);
 	if (initialresponse)
 		free(initialresponse);
-	printfPQExpBuffer(&conn->errorMessage,
-					  libpq_gettext("out of memory\n"));
+	pqReportOOM(conn);
 	return STATUS_ERROR;
 }
 
@@ -663,9 +658,7 @@ pg_SASL_continue(PGconn *conn, int payloadlen, bool final)
 	challenge = malloc(payloadlen + 1);
 	if (!challenge)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("out of memory allocating SASL buffer (%d)\n"),
-						  payloadlen);
+		pqReportOOM(conn);
 		return STATUS_ERROR;
 	}
 
@@ -688,8 +681,8 @@ pg_SASL_continue(PGconn *conn, int payloadlen, bool final)
 		if (outputlen != 0)
 			free(output);
 
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("AuthenticationSASLFinal received from server, but SASL authentication was not completed\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("AuthenticationSASLFinal received from server, but SASL authentication was not completed\n"));
 		return STATUS_ERROR;
 	}
 	if (outputlen != 0)
@@ -758,15 +751,15 @@ pg_local_sendauth(PGconn *conn)
 	{
 		char		sebuf[256];
 
-		printfPQExpBuffer(&conn->errorMessage,
-						  "pg_local_sendauth: sendmsg: %s\n",
+		appendPQExpBuffer(&conn->errorMessage,
+						  libpq_gettext("could not send authentication message: %s\n"),
 						  pqStrerror(errno, sebuf, sizeof(sebuf)));
 		return STATUS_ERROR;
 	}
 	return STATUS_OK;
 #else
-	printfPQExpBuffer(&conn->errorMessage,
-					  libpq_gettext("SCM_CRED authentication method not supported\n"));
+	appendPQExpBufferStr(&conn->errorMessage,
+						 libpq_gettext("SCM_CRED authentication method not supported\n"));
 	return STATUS_ERROR;
 #endif
 }
@@ -798,8 +791,7 @@ pg_password_sendauth(PGconn *conn, const char *password, AuthRequest areq)
 				crypt_pwd = malloc(2 * (MD5_PASSWD_LEN + 1));
 				if (!crypt_pwd)
 				{
-					printfPQExpBuffer(&conn->errorMessage,
-									  libpq_gettext("out of memory\n"));
+					pqReportOOM(conn);
 					return STATUS_ERROR;
 				}
 
@@ -856,13 +848,13 @@ pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn)
 			break;
 
 		case AUTH_REQ_KRB4:
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("Kerberos 4 authentication not supported\n"));
+			appendPQExpBufferStr(&conn->errorMessage,
+								 libpq_gettext("Kerberos 4 authentication not supported\n"));
 			return STATUS_ERROR;
 
 		case AUTH_REQ_KRB5:
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("Kerberos 5 authentication not supported\n"));
+			appendPQExpBufferStr(&conn->errorMessage,
+								 libpq_gettext("Kerberos 5 authentication not supported\n"));
 			return STATUS_ERROR;
 
 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
@@ -932,8 +924,8 @@ pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn)
 			/* No GSSAPI *or* SSPI support */
 		case AUTH_REQ_GSS:
 		case AUTH_REQ_GSS_CONT:
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("GSSAPI authentication not supported\n"));
+			appendPQExpBufferStr(&conn->errorMessage,
+								 libpq_gettext("GSSAPI authentication not supported\n"));
 			return STATUS_ERROR;
 #endif							/* defined(ENABLE_GSS) || defined(ENABLE_SSPI) */
 
@@ -964,16 +956,16 @@ pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn)
 			 */
 #if !defined(ENABLE_GSS)
 		case AUTH_REQ_SSPI:
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("SSPI authentication not supported\n"));
+			appendPQExpBufferStr(&conn->errorMessage,
+								 libpq_gettext("SSPI authentication not supported\n"));
 			return STATUS_ERROR;
 #endif							/* !define(ENABLE_GSSAPI) */
 #endif							/* ENABLE_SSPI */
 
 
 		case AUTH_REQ_CRYPT:
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("Crypt authentication not supported\n"));
+			appendPQExpBufferStr(&conn->errorMessage,
+								 libpq_gettext("Crypt authentication not supported\n"));
 			return STATUS_ERROR;
 
 		case AUTH_REQ_MD5:
@@ -987,14 +979,15 @@ pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn)
 					password = conn->pgpass;
 				if (password == NULL || password[0] == '\0')
 				{
-					printfPQExpBuffer(&conn->errorMessage,
-									  PQnoPasswordSupplied);
+					/* Intentionally not translated. */
+					appendPQExpBufferStr(&conn->errorMessage,
+										 PQnoPasswordSupplied);
 					return STATUS_ERROR;
 				}
 				if (pg_password_sendauth(conn, password, areq) != STATUS_OK)
 				{
-					printfPQExpBuffer(&conn->errorMessage,
-									  "fe_sendauth: error sending password authentication\n");
+					appendPQExpBufferStr(&conn->errorMessage,
+										 libpq_gettext("error sending password authentication\n"));
 					return STATUS_ERROR;
 				}
 				break;
@@ -1017,17 +1010,15 @@ pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn)
 		case AUTH_REQ_SASL_FIN:
 			if (conn->sasl_state == NULL)
 			{
-				printfPQExpBuffer(&conn->errorMessage,
-								  "fe_sendauth: invalid authentication request from server: AUTH_REQ_SASL_CONT without AUTH_REQ_SASL\n");
+				appendPQExpBufferStr(&conn->errorMessage,
+									 libpq_gettext("invalid authentication request from server: AUTH_REQ_SASL_CONT without AUTH_REQ_SASL\n"));
 				return STATUS_ERROR;
 			}
 			if (pg_SASL_continue(conn, payloadlen,
 								 (areq == AUTH_REQ_SASL_FIN)) != STATUS_OK)
 			{
-				/* Use error message, if set already */
-				if (conn->errorMessage.len == 0)
-					printfPQExpBuffer(&conn->errorMessage,
-									  "fe_sendauth: error in SASL authentication\n");
+				appendPQExpBufferStr(&conn->errorMessage,
+									 libpq_gettext("error in SASL authentication\n"));
 				return STATUS_ERROR;
 			}
 			break;
@@ -1038,7 +1029,7 @@ pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn)
 			break;
 
 		default:
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("authentication method %u not supported\n"), areq);
 			return STATUS_ERROR;
 	}
@@ -1052,7 +1043,7 @@ pg_fe_sendauth(AuthRequest areq, int payloadlen, PGconn *conn)
  *
  * Returns a pointer to malloc'd space containing whatever name the user
  * has authenticated to the system.  If there is an error, return NULL,
- * and put a suitable error message in *errorMessage if that's not NULL.
+ * and append a suitable error message to *errorMessage if that's not NULL.
  */
 char *
 pg_fe_getauthname(PQExpBuffer errorMessage)
@@ -1085,7 +1076,7 @@ pg_fe_getauthname(PQExpBuffer errorMessage)
 	if (GetUserName(username, &namesize))
 		name = username;
 	else if (errorMessage)
-		printfPQExpBuffer(errorMessage,
+		appendPQExpBuffer(errorMessage,
 						  libpq_gettext("user name lookup failure: error code %lu\n"),
 						  GetLastError());
 #else
@@ -1095,12 +1086,12 @@ pg_fe_getauthname(PQExpBuffer errorMessage)
 	else if (errorMessage)
 	{
 		if (pwerr != 0)
-			printfPQExpBuffer(errorMessage,
+			appendPQExpBuffer(errorMessage,
 							  libpq_gettext("could not look up local user ID %d: %s\n"),
 							  (int) user_id,
 							  pqStrerror(pwerr, pwdbuf, sizeof(pwdbuf)));
 		else
-			printfPQExpBuffer(errorMessage,
+			appendPQExpBuffer(errorMessage,
 							  libpq_gettext("local user with ID %d does not exist\n"),
 							  (int) user_id);
 	}
@@ -1110,8 +1101,7 @@ pg_fe_getauthname(PQExpBuffer errorMessage)
 	{
 		result = strdup(name);
 		if (result == NULL && errorMessage)
-			printfPQExpBuffer(errorMessage,
-							  libpq_gettext("out of memory\n"));
+			pqReportOOMBuffer(errorMessage);
 	}
 
 	pgunlock_thread();
@@ -1181,12 +1171,16 @@ PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user,
 	if (!conn)
 		return NULL;
 
+	/* This is a library entry point, so start with an empty error message. */
+	resetPQExpBuffer(&conn->errorMessage);
+
 	/* If no algorithm was given, ask the server. */
 	if (algorithm == NULL)
 	{
 		PGresult   *res;
 		char	   *val;
 
+		/* PQexec will reset errorMessage again, but that's OK */
 		res = PQexec(conn, "show password_encryption");
 		if (res == NULL)
 		{
@@ -1202,8 +1196,8 @@ PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user,
 		if (PQntuples(res) != 1 || PQnfields(res) != 1)
 		{
 			PQclear(res);
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("unexpected shape of result set returned for SHOW\n"));
+			appendPQExpBufferStr(&conn->errorMessage,
+								 libpq_gettext("unexpected shape of result set returned for SHOW\n"));
 			return NULL;
 		}
 		val = PQgetvalue(res, 0, 0);
@@ -1211,8 +1205,8 @@ PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user,
 		if (strlen(val) > MAX_ALGORITHM_NAME_LEN)
 		{
 			PQclear(res);
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("password_encryption value too long\n"));
+			appendPQExpBufferStr(&conn->errorMessage,
+								 libpq_gettext("password_encryption value too long\n"));
 			return NULL;
 		}
 		strcpy(algobuf, val);
@@ -1251,15 +1245,14 @@ PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user,
 	}
 	else
 	{
-		printfPQExpBuffer(&conn->errorMessage,
+		appendPQExpBuffer(&conn->errorMessage,
 						  libpq_gettext("unrecognized password encryption algorithm \"%s\"\n"),
 						  algorithm);
 		return NULL;
 	}
 
 	if (!crypt_pwd)
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("out of memory\n"));
+		pqReportOOM(conn);
 
 	return crypt_pwd;
 }
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 9315a27..647423c 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -831,8 +831,7 @@ fillPGconn(PGconn *conn, PQconninfoOption *connOptions)
 				*connmember = strdup(tmp);
 				if (*connmember == NULL)
 				{
-					printfPQExpBuffer(&conn->errorMessage,
-									  libpq_gettext("out of memory\n"));
+					pqReportOOM(conn);
 					return false;
 				}
 			}
@@ -1014,7 +1013,7 @@ connectOptions2(PGconn *conn)
 		if (more || i != conn->nconnhost)
 		{
 			conn->status = CONNECTION_BAD;
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("could not match %d host names to %d hostaddr values\n"),
 							  count_comma_separated_elems(conn->pghost), conn->nconnhost);
 			return false;
@@ -1090,7 +1089,7 @@ connectOptions2(PGconn *conn)
 		else if (more || i != conn->nconnhost)
 		{
 			conn->status = CONNECTION_BAD;
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("could not match %d port numbers to %d hosts\n"),
 							  count_comma_separated_elems(conn->pgport), conn->nconnhost);
 			return false;
@@ -1186,7 +1185,7 @@ connectOptions2(PGconn *conn)
 			&& strcmp(conn->sslmode, "verify-full") != 0)
 		{
 			conn->status = CONNECTION_BAD;
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("invalid sslmode value: \"%s\"\n"),
 							  conn->sslmode);
 			return false;
@@ -1207,7 +1206,7 @@ connectOptions2(PGconn *conn)
 			case 'r':			/* "require" */
 			case 'v':			/* "verify-ca" or "verify-full" */
 				conn->status = CONNECTION_BAD;
-				printfPQExpBuffer(&conn->errorMessage,
+				appendPQExpBuffer(&conn->errorMessage,
 								  libpq_gettext("sslmode value \"%s\" invalid when SSL support is not compiled in\n"),
 								  conn->sslmode);
 				return false;
@@ -1242,7 +1241,7 @@ connectOptions2(PGconn *conn)
 			&& strcmp(conn->target_session_attrs, "read-write") != 0)
 		{
 			conn->status = CONNECTION_BAD;
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("invalid target_session_attrs value: \"%s\"\n"),
 							  conn->target_session_attrs);
 			return false;
@@ -1260,8 +1259,7 @@ connectOptions2(PGconn *conn)
 
 oom_error:
 	conn->status = CONNECTION_BAD;
-	printfPQExpBuffer(&conn->errorMessage,
-					  libpq_gettext("out of memory\n"));
+	pqReportOOM(conn);
 	return false;
 }
 
@@ -1436,8 +1434,7 @@ PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions,
 
 oom_error:
 	conn->status = CONNECTION_BAD;
-	printfPQExpBuffer(&conn->errorMessage,
-					  libpq_gettext("out of memory\n"));
+	pqReportOOM(conn);
 	return conn;
 }
 
@@ -1757,10 +1754,10 @@ connectDBStart(PGconn *conn)
 	conn->outCount = 0;
 
 	/*
-	 * Ensure errorMessage is empty, too.  PQconnectPoll will append messages
-	 * to it in the process of scanning for a working server.  Thus, if we
-	 * fail to connect to multiple hosts, the final error message will include
-	 * details about each failure.
+	 * Ensure errorMessage is empty, too.  PQconnectPoll and its subroutines
+	 * will append messages to it in the process of scanning for a working
+	 * server.  Thus, if we fail to connect to multiple hosts, the final error
+	 * message will include details about each failure.
 	 */
 	resetPQExpBuffer(&conn->errorMessage);
 
@@ -1955,12 +1952,6 @@ connectDBComplete(PGconn *conn)
 		switch (flag)
 		{
 			case PGRES_POLLING_OK:
-
-				/*
-				 * Reset stored error messages since we now have a working
-				 * connection
-				 */
-				resetPQExpBuffer(&conn->errorMessage);
 				return 1;		/* success! */
 
 			case PGRES_POLLING_READING:
@@ -2005,46 +1996,6 @@ connectDBComplete(PGconn *conn)
 	}
 }
 
-/*
- * This subroutine saves conn->errorMessage, which will be restored back by
- * restoreErrorMessage subroutine.  Returns false on OOM failure.
- */
-static bool
-saveErrorMessage(PGconn *conn, PQExpBuffer savedMessage)
-{
-	initPQExpBuffer(savedMessage);
-	appendPQExpBufferStr(savedMessage,
-						 conn->errorMessage.data);
-	if (PQExpBufferBroken(savedMessage))
-	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("out of memory\n"));
-		return false;
-	}
-	/* Clear whatever is in errorMessage now */
-	resetPQExpBuffer(&conn->errorMessage);
-	return true;
-}
-
-/*
- * Restores saved error messages back to conn->errorMessage, prepending them
- * to whatever is in conn->errorMessage already.  (This does the right thing
- * if anything's been added to conn->errorMessage since saveErrorMessage.)
- */
-static void
-restoreErrorMessage(PGconn *conn, PQExpBuffer savedMessage)
-{
-	appendPQExpBufferStr(savedMessage, conn->errorMessage.data);
-	resetPQExpBuffer(&conn->errorMessage);
-	appendPQExpBufferStr(&conn->errorMessage, savedMessage->data);
-	/* If any step above hit OOM, just report that */
-	if (PQExpBufferBroken(savedMessage) ||
-		PQExpBufferBroken(&conn->errorMessage))
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("out of memory\n"));
-	termPQExpBuffer(savedMessage);
-}
-
 /* ----------------
  *		PQconnectPoll
  *
@@ -2080,7 +2031,6 @@ PQconnectPoll(PGconn *conn)
 	PGresult   *res;
 	char		sebuf[256];
 	int			optval;
-	PQExpBufferData savedMessage;
 
 	if (conn == NULL)
 		return PGRES_POLLING_FAILED;
@@ -2601,12 +2551,7 @@ keep_going:						/* We will come back to here until there is
 														EnvironmentOptions);
 				if (!startpacket)
 				{
-					/*
-					 * will not appendbuffer here, since it's likely to also
-					 * run out of memory
-					 */
-					printfPQExpBuffer(&conn->errorMessage,
-									  libpq_gettext("out of memory\n"));
+					pqReportOOM(conn);
 					goto error_return;
 				}
 
@@ -2992,7 +2937,6 @@ keep_going:						/* We will come back to here until there is
 				 * avoid the Kerberos code doing a hostname look-up.
 				 */
 				res = pg_fe_sendauth(areq, msgLength, conn);
-				conn->errorMessage.len = strlen(conn->errorMessage.data);
 
 				/* OK, we have processed the message; mark data consumed */
 				conn->inStart = conn->inCursor;
@@ -3112,31 +3056,19 @@ keep_going:						/* We will come back to here until there is
 					conn->target_session_attrs != NULL &&
 					strcmp(conn->target_session_attrs, "read-write") == 0)
 				{
-					/*
-					 * Save existing error messages across the PQsendQuery
-					 * attempt.  This is necessary because PQsendQuery is
-					 * going to reset conn->errorMessage, so we would lose
-					 * error messages related to previous hosts we have tried
-					 * and failed to connect to.
-					 */
-					if (!saveErrorMessage(conn, &savedMessage))
-						goto error_return;
-
-					conn->status = CONNECTION_OK;
 					if (!PQsendQuery(conn,
 									 "SHOW transaction_read_only"))
-					{
-						restoreErrorMessage(conn, &savedMessage);
 						goto error_return;
-					}
 					conn->status = CONNECTION_CHECK_WRITABLE;
-					restoreErrorMessage(conn, &savedMessage);
 					return PGRES_POLLING_READING;
 				}
 
 				/* We can release the address lists now. */
 				release_all_addrinfo(conn);
 
+				/* Likewise drop any stored error messages. */
+				resetPQExpBuffer(&conn->errorMessage);
+
 				/* We are open for business! */
 				conn->status = CONNECTION_OK;
 				return PGRES_POLLING_OK;
@@ -3146,23 +3078,16 @@ keep_going:						/* We will come back to here until there is
 
 			/*
 			 * Do post-connection housekeeping (only needed in protocol 2.0).
-			 *
-			 * We pretend that the connection is OK for the duration of these
-			 * queries.
 			 */
-			conn->status = CONNECTION_OK;
-
 			switch (pqSetenvPoll(conn))
 			{
 				case PGRES_POLLING_OK:	/* Success */
 					break;
 
 				case PGRES_POLLING_READING: /* Still going */
-					conn->status = CONNECTION_SETENV;
 					return PGRES_POLLING_READING;
 
 				case PGRES_POLLING_WRITING: /* Still going */
-					conn->status = CONNECTION_SETENV;
 					return PGRES_POLLING_WRITING;
 
 				default:
@@ -3182,39 +3107,30 @@ keep_going:						/* We will come back to here until there is
 				conn->target_session_attrs != NULL &&
 				strcmp(conn->target_session_attrs, "read-write") == 0)
 			{
-				if (!saveErrorMessage(conn, &savedMessage))
-					goto error_return;
-
-				conn->status = CONNECTION_OK;
 				if (!PQsendQuery(conn,
 								 "SHOW transaction_read_only"))
-				{
-					restoreErrorMessage(conn, &savedMessage);
 					goto error_return;
-				}
 				conn->status = CONNECTION_CHECK_WRITABLE;
-				restoreErrorMessage(conn, &savedMessage);
 				return PGRES_POLLING_READING;
 			}
 
 			/* We can release the address lists now. */
 			release_all_addrinfo(conn);
 
+			/* Likewise drop any stored error messages. */
+			resetPQExpBuffer(&conn->errorMessage);
+
 			/* We are open for business! */
 			conn->status = CONNECTION_OK;
 			return PGRES_POLLING_OK;
 
 		case CONNECTION_CONSUME:
 			{
-				conn->status = CONNECTION_OK;
 				if (!PQconsumeInput(conn))
 					goto error_return;
 
 				if (PQisBusy(conn))
-				{
-					conn->status = CONNECTION_CONSUME;
 					return PGRES_POLLING_READING;
-				}
 
 				/*
 				 * Call PQgetResult() again to consume NULL result.
@@ -3223,10 +3139,15 @@ keep_going:						/* We will come back to here until there is
 				if (res != NULL)
 				{
 					PQclear(res);
-					conn->status = CONNECTION_CONSUME;
 					goto keep_going;
 				}
 
+				/* We can release the address lists now. */
+				release_all_addrinfo(conn);
+
+				/* Likewise drop any stored error messages. */
+				resetPQExpBuffer(&conn->errorMessage);
+
 				/* We are open for business! */
 				conn->status = CONNECTION_OK;
 				return PGRES_POLLING_OK;
@@ -3236,22 +3157,11 @@ keep_going:						/* We will come back to here until there is
 				const char *displayed_host;
 				const char *displayed_port;
 
-				if (!saveErrorMessage(conn, &savedMessage))
-					goto error_return;
-
-				conn->status = CONNECTION_OK;
 				if (!PQconsumeInput(conn))
-				{
-					restoreErrorMessage(conn, &savedMessage);
 					goto error_return;
-				}
 
 				if (PQisBusy(conn))
-				{
-					conn->status = CONNECTION_CHECK_WRITABLE;
-					restoreErrorMessage(conn, &savedMessage);
 					return PGRES_POLLING_READING;
-				}
 
 				res = PQgetResult(conn);
 				if (res && (PQresultStatus(res) == PGRES_TUPLES_OK) &&
@@ -3267,7 +3177,6 @@ keep_going:						/* We will come back to here until there is
 						const char *displayed_port;
 
 						PQclear(res);
-						restoreErrorMessage(conn, &savedMessage);
 
 						/* Append error report to conn->errorMessage. */
 						if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
@@ -3298,10 +3207,6 @@ keep_going:						/* We will come back to here until there is
 
 					/* Session is read-write, so we're good. */
 					PQclear(res);
-					termPQExpBuffer(&savedMessage);
-
-					/* We can release the address lists now. */
-					release_all_addrinfo(conn);
 
 					/*
 					 * Finish reading any remaining messages before being
@@ -3317,7 +3222,6 @@ keep_going:						/* We will come back to here until there is
 				 */
 				if (res)
 					PQclear(res);
-				restoreErrorMessage(conn, &savedMessage);
 
 				/* Append error report to conn->errorMessage. */
 				if (conn->connhost[conn->whichhost].type == CHT_HOST_ADDRESS)
@@ -3771,7 +3675,7 @@ PQreset(PGconn *conn)
 										  conn->events[i].passThrough))
 				{
 					conn->status = CONNECTION_BAD;
-					printfPQExpBuffer(&conn->errorMessage,
+					appendPQExpBuffer(&conn->errorMessage,
 									  libpq_gettext("PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n"),
 									  conn->events[i].name);
 					break;
@@ -3831,7 +3735,7 @@ PQresetPoll(PGconn *conn)
 										  conn->events[i].passThrough))
 				{
 					conn->status = CONNECTION_BAD;
-					printfPQExpBuffer(&conn->errorMessage,
+					appendPQExpBuffer(&conn->errorMessage,
 									  libpq_gettext("PGEventProc \"%s\" failed during PGEVT_CONNRESET event\n"),
 									  conn->events[i].name);
 					return PGRES_POLLING_FAILED;
@@ -4166,7 +4070,7 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 
 	if ((url = strdup(purl)) == NULL)
 	{
-		printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
+		pqReportOOM(conn);
 		return 3;
 	}
 
@@ -4178,8 +4082,9 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 
 	if (pg_strncasecmp(url, LDAP_URL, strlen(LDAP_URL)) != 0)
 	{
-		printfPQExpBuffer(errorMessage,
-						  libpq_gettext("invalid LDAP URL \"%s\": scheme must be ldap://\n"), purl);
+		appendPQExpBuffer(errorMessage,
+						  libpq_gettext("invalid LDAP URL \"%s\": scheme must be ldap://\n"),
+						  purl);
 		free(url);
 		return 3;
 	}
@@ -4193,8 +4098,9 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 	p = strchr(url + strlen(LDAP_URL), '/');
 	if (p == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
 	{
-		printfPQExpBuffer(errorMessage, libpq_gettext(
-													  "invalid LDAP URL \"%s\": missing distinguished name\n"), purl);
+		appendPQExpBuffer(errorMessage,
+						  libpq_gettext("invalid LDAP URL \"%s\": missing distinguished name\n"),
+						  purl);
 		free(url);
 		return 3;
 	}
@@ -4204,8 +4110,9 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 	/* attribute */
 	if ((p = strchr(dn, '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
 	{
-		printfPQExpBuffer(errorMessage, libpq_gettext(
-													  "invalid LDAP URL \"%s\": must have exactly one attribute\n"), purl);
+		appendPQExpBuffer(errorMessage,
+						  libpq_gettext("invalid LDAP URL \"%s\": must have exactly one attribute\n"),
+						  purl);
 		free(url);
 		return 3;
 	}
@@ -4215,7 +4122,9 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 	/* scope */
 	if ((p = strchr(attrs[0], '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
 	{
-		printfPQExpBuffer(errorMessage, libpq_gettext("invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n"), purl);
+		appendPQExpBuffer(errorMessage,
+						  libpq_gettext("invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n"),
+						  purl);
 		free(url);
 		return 3;
 	}
@@ -4225,7 +4134,7 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 	/* filter */
 	if ((p = strchr(scopestr, '?')) == NULL || *(p + 1) == '\0' || *(p + 1) == '?')
 	{
-		printfPQExpBuffer(errorMessage,
+		appendPQExpBuffer(errorMessage,
 						  libpq_gettext("invalid LDAP URL \"%s\": no filter\n"), purl);
 		free(url);
 		return 3;
@@ -4246,8 +4155,9 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 		lport = strtol(portstr, &endptr, 10);
 		if (*portstr == '\0' || *endptr != '\0' || errno || lport < 0 || lport > 65535)
 		{
-			printfPQExpBuffer(errorMessage, libpq_gettext(
-														  "invalid LDAP URL \"%s\": invalid port number\n"), purl);
+			appendPQExpBuffer(errorMessage,
+							  libpq_gettext("invalid LDAP URL \"%s\": invalid port number\n"),
+							  purl);
 			free(url);
 			return 3;
 		}
@@ -4257,8 +4167,9 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 	/* Allow only one attribute */
 	if (strchr(attrs[0], ',') != NULL)
 	{
-		printfPQExpBuffer(errorMessage, libpq_gettext(
-													  "invalid LDAP URL \"%s\": must have exactly one attribute\n"), purl);
+		appendPQExpBuffer(errorMessage,
+						  libpq_gettext("invalid LDAP URL \"%s\": must have exactly one attribute\n"),
+						  purl);
 		free(url);
 		return 3;
 	}
@@ -4272,7 +4183,9 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 		scope = LDAP_SCOPE_SUBTREE;
 	else
 	{
-		printfPQExpBuffer(errorMessage, libpq_gettext("invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n"), purl);
+		appendPQExpBuffer(errorMessage,
+						  libpq_gettext("invalid LDAP URL \"%s\": must have search scope (base/one/sub)\n"),
+						  purl);
 		free(url);
 		return 3;
 	}
@@ -4280,8 +4193,8 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 	/* initialize LDAP structure */
 	if ((ld = ldap_init(hostname, port)) == NULL)
 	{
-		printfPQExpBuffer(errorMessage,
-						  libpq_gettext("could not create LDAP structure\n"));
+		appendPQExpBufferStr(errorMessage,
+							 libpq_gettext("could not create LDAP structure\n"));
 		free(url);
 		return 3;
 	}
@@ -4356,7 +4269,7 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 	{
 		if (res != NULL)
 			ldap_msgfree(res);
-		printfPQExpBuffer(errorMessage,
+		appendPQExpBuffer(errorMessage,
 						  libpq_gettext("lookup on LDAP server failed: %s\n"),
 						  ldap_err2string(rc));
 		ldap_unbind(ld);
@@ -4367,9 +4280,9 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 	/* complain if there was not exactly one result */
 	if ((rc = ldap_count_entries(ld, res)) != 1)
 	{
-		printfPQExpBuffer(errorMessage,
-						  rc ? libpq_gettext("more than one entry found on LDAP lookup\n")
-						  : libpq_gettext("no entry found on LDAP lookup\n"));
+		appendPQExpBufferStr(errorMessage,
+							 rc ? libpq_gettext("more than one entry found on LDAP lookup\n")
+							 : libpq_gettext("no entry found on LDAP lookup\n"));
 		ldap_msgfree(res);
 		ldap_unbind(ld);
 		free(url);
@@ -4380,8 +4293,8 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 	if ((entry = ldap_first_entry(ld, res)) == NULL)
 	{
 		/* should never happen */
-		printfPQExpBuffer(errorMessage,
-						  libpq_gettext("no entry found on LDAP lookup\n"));
+		appendPQExpBufferStr(errorMessage,
+							 libpq_gettext("no entry found on LDAP lookup\n"));
 		ldap_msgfree(res);
 		ldap_unbind(ld);
 		free(url);
@@ -4391,8 +4304,8 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 	/* get values */
 	if ((values = ldap_get_values_len(ld, entry, attrs[0])) == NULL)
 	{
-		printfPQExpBuffer(errorMessage,
-						  libpq_gettext("attribute has no values on LDAP lookup\n"));
+		appendPQExpBufferStr(errorMessage,
+							 libpq_gettext("attribute has no values on LDAP lookup\n"));
 		ldap_msgfree(res);
 		ldap_unbind(ld);
 		free(url);
@@ -4404,8 +4317,8 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 
 	if (values[0] == NULL)
 	{
-		printfPQExpBuffer(errorMessage,
-						  libpq_gettext("attribute has no values on LDAP lookup\n"));
+		appendPQExpBufferStr(errorMessage,
+							 libpq_gettext("attribute has no values on LDAP lookup\n"));
 		ldap_value_free_len(values);
 		ldap_unbind(ld);
 		return 1;
@@ -4417,10 +4330,9 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 		size += values[i]->bv_len + 1;
 	if ((result = malloc(size)) == NULL)
 	{
-		printfPQExpBuffer(errorMessage,
-						  libpq_gettext("out of memory\n"));
 		ldap_value_free_len(values);
 		ldap_unbind(ld);
+		pqReportOOMBuffer(errorMessage);
 		return 3;
 	}
 	p = result;
@@ -4456,8 +4368,8 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 				}
 				else if (ld_is_nl_cr(*p))
 				{
-					printfPQExpBuffer(errorMessage, libpq_gettext(
-																  "missing \"=\" after \"%s\" in connection info string\n"),
+					appendPQExpBuffer(errorMessage,
+									  libpq_gettext("missing \"=\" after \"%s\" in connection info string\n"),
 									  optname);
 					free(result);
 					return 3;
@@ -4475,8 +4387,8 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 				}
 				else if (!ld_is_sp_tab(*p))
 				{
-					printfPQExpBuffer(errorMessage, libpq_gettext(
-																  "missing \"=\" after \"%s\" in connection info string\n"),
+					appendPQExpBuffer(errorMessage,
+									  libpq_gettext("missing \"=\" after \"%s\" in connection info string\n"),
 									  optname);
 					free(result);
 					return 3;
@@ -4536,9 +4448,8 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 						options[i].val = strdup(optval);
 						if (!options[i].val)
 						{
-							printfPQExpBuffer(errorMessage,
-											  libpq_gettext("out of memory\n"));
 							free(result);
+							pqReportOOMBuffer(errorMessage);
 							return 3;
 						}
 					}
@@ -4548,7 +4459,7 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 			}
 			if (!found_keyword)
 			{
-				printfPQExpBuffer(errorMessage,
+				appendPQExpBuffer(errorMessage,
 								  libpq_gettext("invalid connection option \"%s\"\n"),
 								  optname);
 				free(result);
@@ -4564,8 +4475,8 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
 
 	if (state == 5 || state == 6)
 	{
-		printfPQExpBuffer(errorMessage, libpq_gettext(
-													  "unterminated quoted string in connection info string\n"));
+		appendPQExpBufferStr(errorMessage,
+							 libpq_gettext("unterminated quoted string in connection info string\n"));
 		return 3;
 	}
 
@@ -4583,8 +4494,8 @@ ldapServiceLookup(const char *purl, PQconninfoOption *options,
  * Returns 0 on success, nonzero on failure.  On failure, if errorMessage
  * isn't null, also store an error message there.  (Note: the only reason
  * this function and related ones don't dump core on errorMessage == NULL
- * is the undocumented fact that printfPQExpBuffer does nothing when passed
- * a null PQExpBuffer pointer.)
+ * is the undocumented fact that printfPQExpBuffer and friends do nothing
+ * when passed a null PQExpBuffer pointer.)
  */
 static int
 parseServiceInfo(PQconninfoOption *options, PQExpBuffer errorMessage)
@@ -4647,7 +4558,7 @@ next_file:
 last_file:
 	if (!group_found)
 	{
-		printfPQExpBuffer(errorMessage,
+		appendPQExpBuffer(errorMessage,
 						  libpq_gettext("definition of service \"%s\" not found\n"), service);
 		return 3;
 	}
@@ -4671,7 +4582,7 @@ parseServiceFile(const char *serviceFile,
 	f = fopen(serviceFile, "r");
 	if (f == NULL)
 	{
-		printfPQExpBuffer(errorMessage, libpq_gettext("service file \"%s\" not found\n"),
+		appendPQExpBuffer(errorMessage, libpq_gettext("service file \"%s\" not found\n"),
 						  serviceFile);
 		return 1;
 	}
@@ -4683,7 +4594,7 @@ parseServiceFile(const char *serviceFile,
 		if (strlen(line) >= sizeof(buf) - 1)
 		{
 			fclose(f);
-			printfPQExpBuffer(errorMessage,
+			appendPQExpBuffer(errorMessage,
 							  libpq_gettext("line %d too long in service file \"%s\"\n"),
 							  linenr,
 							  serviceFile);
@@ -4754,7 +4665,7 @@ parseServiceFile(const char *serviceFile,
 				val = strchr(line, '=');
 				if (val == NULL)
 				{
-					printfPQExpBuffer(errorMessage,
+					appendPQExpBuffer(errorMessage,
 									  libpq_gettext("syntax error in service file \"%s\", line %d\n"),
 									  serviceFile,
 									  linenr);
@@ -4765,7 +4676,7 @@ parseServiceFile(const char *serviceFile,
 
 				if (strcmp(key, "service") == 0)
 				{
-					printfPQExpBuffer(errorMessage,
+					appendPQExpBuffer(errorMessage,
 									  libpq_gettext("nested service specifications not supported in service file \"%s\", line %d\n"),
 									  serviceFile,
 									  linenr);
@@ -4786,9 +4697,8 @@ parseServiceFile(const char *serviceFile,
 							options[i].val = strdup(val);
 						if (!options[i].val)
 						{
-							printfPQExpBuffer(errorMessage,
-											  libpq_gettext("out of memory\n"));
 							fclose(f);
+							pqReportOOMBuffer(errorMessage);
 							return 3;
 						}
 						found_keyword = true;
@@ -4798,7 +4708,7 @@ parseServiceFile(const char *serviceFile,
 
 				if (!found_keyword)
 				{
-					printfPQExpBuffer(errorMessage,
+					appendPQExpBuffer(errorMessage,
 									  libpq_gettext("syntax error in service file \"%s\", line %d\n"),
 									  serviceFile,
 									  linenr);
@@ -4842,7 +4752,7 @@ PQconninfoParse(const char *conninfo, char **errmsg)
 	if (PQExpBufferDataBroken(errorBuf))
 		return NULL;			/* out of memory already :-( */
 	connOptions = parse_connection_string(conninfo, &errorBuf, false);
-	if (connOptions == NULL && errmsg)
+	if (connOptions == NULL && errmsg && !PQExpBufferDataBroken(errorBuf))
 		*errmsg = errorBuf.data;
 	else
 		termPQExpBuffer(&errorBuf);
@@ -4866,8 +4776,7 @@ conninfo_init(PQExpBuffer errorMessage)
 	options = (PQconninfoOption *) malloc(sizeof(PQconninfoOption) * sizeof(PQconninfoOptions) / sizeof(PQconninfoOptions[0]));
 	if (options == NULL)
 	{
-		printfPQExpBuffer(errorMessage,
-						  libpq_gettext("out of memory\n"));
+		pqReportOOMBuffer(errorMessage);
 		return NULL;
 	}
 	opt_dest = options;
@@ -4965,9 +4874,8 @@ conninfo_parse(const char *conninfo, PQExpBuffer errorMessage,
 	/* Need a modifiable copy of the input string */
 	if ((buf = strdup(conninfo)) == NULL)
 	{
-		printfPQExpBuffer(errorMessage,
-						  libpq_gettext("out of memory\n"));
 		PQconninfoFree(options);
+		pqReportOOMBuffer(errorMessage);
 		return NULL;
 	}
 	cp = buf;
@@ -5004,7 +4912,7 @@ conninfo_parse(const char *conninfo, PQExpBuffer errorMessage,
 		/* Check that there is a following '=' */
 		if (*cp != '=')
 		{
-			printfPQExpBuffer(errorMessage,
+			appendPQExpBuffer(errorMessage,
 							  libpq_gettext("missing \"=\" after \"%s\" in connection info string\n"),
 							  pname);
 			PQconninfoFree(options);
@@ -5053,8 +4961,8 @@ conninfo_parse(const char *conninfo, PQExpBuffer errorMessage,
 			{
 				if (*cp == '\0')
 				{
-					printfPQExpBuffer(errorMessage,
-									  libpq_gettext("unterminated quoted string in connection info string\n"));
+					appendPQExpBufferStr(errorMessage,
+										 libpq_gettext("unterminated quoted string in connection info string\n"));
 					PQconninfoFree(options);
 					free(buf);
 					return NULL;
@@ -5189,7 +5097,7 @@ conninfo_array_parse(const char *const *keywords, const char *const *values,
 			/* Check for invalid connection option */
 			if (option->keyword == NULL)
 			{
-				printfPQExpBuffer(errorMessage,
+				appendPQExpBuffer(errorMessage,
 								  libpq_gettext("invalid connection option \"%s\"\n"),
 								  pname);
 				PQconninfoFree(options);
@@ -5221,10 +5129,9 @@ conninfo_array_parse(const char *const *keywords, const char *const *values,
 								options[k].val = strdup(str_option->val);
 								if (!options[k].val)
 								{
-									printfPQExpBuffer(errorMessage,
-													  libpq_gettext("out of memory\n"));
 									PQconninfoFree(options);
 									PQconninfoFree(dbname_options);
+									pqReportOOMBuffer(errorMessage);
 									return NULL;
 								}
 								break;
@@ -5250,10 +5157,9 @@ conninfo_array_parse(const char *const *keywords, const char *const *values,
 				option->val = strdup(pvalue);
 				if (!option->val)
 				{
-					printfPQExpBuffer(errorMessage,
-									  libpq_gettext("out of memory\n"));
 					PQconninfoFree(options);
 					PQconninfoFree(dbname_options);
+					pqReportOOMBuffer(errorMessage);
 					return NULL;
 				}
 			}
@@ -5322,8 +5228,7 @@ conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
 				if (!option->val)
 				{
 					if (errorMessage)
-						printfPQExpBuffer(errorMessage,
-										  libpq_gettext("out of memory\n"));
+						pqReportOOMBuffer(errorMessage);
 					return false;
 				}
 				continue;
@@ -5346,8 +5251,7 @@ conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
 				if (!option->val)
 				{
 					if (errorMessage)
-						printfPQExpBuffer(errorMessage,
-										  libpq_gettext("out of memory\n"));
+						pqReportOOMBuffer(errorMessage);
 					return false;
 				}
 				continue;
@@ -5364,8 +5268,7 @@ conninfo_add_defaults(PQconninfoOption *options, PQExpBuffer errorMessage)
 			if (!option->val)
 			{
 				if (errorMessage)
-					printfPQExpBuffer(errorMessage,
-									  libpq_gettext("out of memory\n"));
+					pqReportOOMBuffer(errorMessage);
 				return false;
 			}
 			continue;
@@ -5465,8 +5368,7 @@ conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
 	initPQExpBuffer(&portbuf);
 	if (PQExpBufferDataBroken(hostbuf) || PQExpBufferDataBroken(portbuf))
 	{
-		printfPQExpBuffer(errorMessage,
-						  libpq_gettext("out of memory\n"));
+		pqReportOOMBuffer(errorMessage);
 		goto cleanup;
 	}
 
@@ -5474,8 +5376,7 @@ conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
 	buf = strdup(uri);
 	if (buf == NULL)
 	{
-		printfPQExpBuffer(errorMessage,
-						  libpq_gettext("out of memory\n"));
+		pqReportOOMBuffer(errorMessage);
 		goto cleanup;
 	}
 	start = buf;
@@ -5485,7 +5386,7 @@ conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
 	if (prefix_len == 0)
 	{
 		/* Should never happen */
-		printfPQExpBuffer(errorMessage,
+		appendPQExpBuffer(errorMessage,
 						  libpq_gettext("invalid URI propagated to internal parser routine: \"%s\"\n"),
 						  uri);
 		goto cleanup;
@@ -5562,14 +5463,14 @@ conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
 				++p;
 			if (!*p)
 			{
-				printfPQExpBuffer(errorMessage,
+				appendPQExpBuffer(errorMessage,
 								  libpq_gettext("end of string reached when looking for matching \"]\" in IPv6 host address in URI: \"%s\"\n"),
 								  uri);
 				goto cleanup;
 			}
 			if (p == host)
 			{
-				printfPQExpBuffer(errorMessage,
+				appendPQExpBuffer(errorMessage,
 								  libpq_gettext("IPv6 host address may not be empty in URI: \"%s\"\n"),
 								  uri);
 				goto cleanup;
@@ -5584,7 +5485,7 @@ conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
 			 */
 			if (*p && *p != ':' && *p != '/' && *p != '?' && *p != ',')
 			{
-				printfPQExpBuffer(errorMessage,
+				appendPQExpBuffer(errorMessage,
 								  libpq_gettext("unexpected character \"%c\" at position %d in URI (expected \":\" or \"/\"): \"%s\"\n"),
 								  *p, (int) (p - buf + 1), uri);
 				goto cleanup;
@@ -5713,7 +5614,7 @@ conninfo_uri_parse_params(char *params,
 				/* Was there '=' already? */
 				if (value != NULL)
 				{
-					printfPQExpBuffer(errorMessage,
+					appendPQExpBuffer(errorMessage,
 									  libpq_gettext("extra key/value separator \"=\" in URI query parameter: \"%s\"\n"),
 									  keyword);
 					return false;
@@ -5733,7 +5634,7 @@ conninfo_uri_parse_params(char *params,
 				/* Was there '=' at all? */
 				if (value == NULL)
 				{
-					printfPQExpBuffer(errorMessage,
+					appendPQExpBuffer(errorMessage,
 									  libpq_gettext("missing key/value separator \"=\" in URI query parameter: \"%s\"\n"),
 									  keyword);
 					return false;
@@ -5784,7 +5685,7 @@ conninfo_uri_parse_params(char *params,
 		{
 			/* Insert generic message if conninfo_storeval didn't give one. */
 			if (errorMessage->len == 0)
-				printfPQExpBuffer(errorMessage,
+				appendPQExpBuffer(errorMessage,
 								  libpq_gettext("invalid URI query parameter: \"%s\"\n"),
 								  keyword);
 			/* And fail. */
@@ -5831,7 +5732,7 @@ conninfo_uri_decode(const char *str, PQExpBuffer errorMessage)
 	buf = malloc(strlen(str) + 1);
 	if (buf == NULL)
 	{
-		printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
+		pqReportOOMBuffer(errorMessage);
 		return NULL;
 	}
 	p = buf;
@@ -5858,7 +5759,7 @@ conninfo_uri_decode(const char *str, PQExpBuffer errorMessage)
 			 */
 			if (!(get_hexdigit(*q++, &hi) && get_hexdigit(*q++, &lo)))
 			{
-				printfPQExpBuffer(errorMessage,
+				appendPQExpBuffer(errorMessage,
 								  libpq_gettext("invalid percent-encoded token: \"%s\"\n"),
 								  str);
 				free(buf);
@@ -5868,7 +5769,7 @@ conninfo_uri_decode(const char *str, PQExpBuffer errorMessage)
 			c = (hi << 4) | lo;
 			if (c == 0)
 			{
-				printfPQExpBuffer(errorMessage,
+				appendPQExpBuffer(errorMessage,
 								  libpq_gettext("forbidden value %%00 in percent-encoded value: \"%s\"\n"),
 								  str);
 				free(buf);
@@ -5963,7 +5864,7 @@ conninfo_storeval(PQconninfoOption *connOptions,
 	if (option == NULL)
 	{
 		if (!ignoreMissing)
-			printfPQExpBuffer(errorMessage,
+			appendPQExpBuffer(errorMessage,
 							  libpq_gettext("invalid connection option \"%s\"\n"),
 							  keyword);
 		return NULL;
@@ -5981,7 +5882,7 @@ conninfo_storeval(PQconninfoOption *connOptions,
 		value_copy = strdup(value);
 		if (value_copy == NULL)
 		{
-			printfPQExpBuffer(errorMessage, libpq_gettext("out of memory\n"));
+			pqReportOOMBuffer(errorMessage);
 			return NULL;
 		}
 	}
diff --git a/src/interfaces/libpq/fe-exec.c b/src/interfaces/libpq/fe-exec.c
index 4c0114c..2c1baa7 100644
--- a/src/interfaces/libpq/fe-exec.c
+++ b/src/interfaces/libpq/fe-exec.c
@@ -770,8 +770,7 @@ pqSaveErrorResult(PGconn *conn)
  * This subroutine prepares an async result object for return to the caller.
  * If there is not already an async result object, build an error object
  * using whatever is in conn->errorMessage.  In any case, clear the async
- * result storage and make sure PQerrorMessage will agree with the result's
- * error string.
+ * result storage.
  */
 PGresult *
 pqPrepareAsyncResult(PGconn *conn)
@@ -781,21 +780,11 @@ pqPrepareAsyncResult(PGconn *conn)
 	/*
 	 * conn->result is the PGresult to return.  If it is NULL (which probably
 	 * shouldn't happen) we assume there is an appropriate error message in
-	 * conn->errorMessage.
+	 * conn->errorMessage, and copy that into a PGresult.
 	 */
 	res = conn->result;
 	if (!res)
 		res = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
-	else
-	{
-		/*
-		 * Make sure PQerrorMessage agrees with result; it could be different
-		 * if we have concatenated messages.
-		 */
-		resetPQExpBuffer(&conn->errorMessage);
-		appendPQExpBufferStr(&conn->errorMessage,
-							 PQresultErrorMessage(res));
-	}
 
 	/*
 	 * Replace conn->result with next_result, if any.  In the normal case
@@ -1188,8 +1177,8 @@ PQsendQuery(PGconn *conn, const char *query)
 	/* check the argument */
 	if (!query)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("command string is a null pointer\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("command string is a null pointer\n"));
 		return 0;
 	}
 
@@ -1246,14 +1235,14 @@ PQsendQueryParams(PGconn *conn,
 	/* check the arguments */
 	if (!command)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("command string is a null pointer\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("command string is a null pointer\n"));
 		return 0;
 	}
 	if (nParams < 0 || nParams > 65535)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("number of parameters must be between 0 and 65535\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("number of parameters must be between 0 and 65535\n"));
 		return 0;
 	}
 
@@ -1286,28 +1275,28 @@ PQsendPrepare(PGconn *conn,
 	/* check the arguments */
 	if (!stmtName)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("statement name is a null pointer\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("statement name is a null pointer\n"));
 		return 0;
 	}
 	if (!query)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("command string is a null pointer\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("command string is a null pointer\n"));
 		return 0;
 	}
 	if (nParams < 0 || nParams > 65535)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("number of parameters must be between 0 and 65535\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("number of parameters must be between 0 and 65535\n"));
 		return 0;
 	}
 
 	/* This isn't gonna work on a 2.0 server */
 	if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("function requires at least protocol version 3.0\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("function requires at least protocol version 3.0\n"));
 		return 0;
 	}
 
@@ -1387,14 +1376,14 @@ PQsendQueryPrepared(PGconn *conn,
 	/* check the arguments */
 	if (!stmtName)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("statement name is a null pointer\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("statement name is a null pointer\n"));
 		return 0;
 	}
 	if (nParams < 0 || nParams > 65535)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("number of parameters must be between 0 and 65535\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("number of parameters must be between 0 and 65535\n"));
 		return 0;
 	}
 
@@ -1418,21 +1407,32 @@ PQsendQueryStart(PGconn *conn)
 	if (!conn)
 		return false;
 
-	/* clear the error string */
-	resetPQExpBuffer(&conn->errorMessage);
+	/*
+	 * Clear the error string at start of a new query.  All libpq code
+	 * executed while we're running a query should append messages to
+	 * errorMessage.
+	 *
+	 * However, if we're in a connecting state (anything but CONNECTION_OK or
+	 * CONNECTION_BAD), then we don't want to clear the errorMessage.  We must
+	 * be doing some libpq-generated query to check server state, and we want
+	 * to continue building up the history of connection attempts across
+	 * multiple servers --- see comments in connectDBStart.
+	 */
+	if (conn->status <= CONNECTION_BAD)
+		resetPQExpBuffer(&conn->errorMessage);
 
 	/* Don't try to send if we know there's no live connection. */
-	if (conn->status != CONNECTION_OK)
+	if (conn->status == CONNECTION_BAD)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("no connection to the server\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("no connection to the server\n"));
 		return false;
 	}
 	/* Can't send while already busy, either. */
 	if (conn->asyncStatus != PGASYNC_IDLE)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("another command is already in progress\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("another command is already in progress\n"));
 		return false;
 	}
 
@@ -1469,8 +1469,8 @@ PQsendQueryGuts(PGconn *conn,
 	/* This isn't gonna work on a 2.0 server */
 	if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("function requires at least protocol version 3.0\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("function requires at least protocol version 3.0\n"));
 		return 0;
 	}
 
@@ -1545,8 +1545,8 @@ PQsendQueryGuts(PGconn *conn,
 					nbytes = paramLengths[i];
 				else
 				{
-					printfPQExpBuffer(&conn->errorMessage,
-									  libpq_gettext("length must be given for binary parameter\n"));
+					appendPQExpBufferStr(&conn->errorMessage,
+										 libpq_gettext("length must be given for binary parameter\n"));
 					goto sendFailed;
 				}
 			}
@@ -1817,7 +1817,7 @@ PQgetResult(PGconn *conn)
 			res = getCopyResult(conn, PGRES_COPY_BOTH);
 			break;
 		default:
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("unexpected asyncStatus: %d\n"),
 							  (int) conn->asyncStatus);
 			res = PQmakeEmptyPGresult(conn, PGRES_FATAL_ERROR);
@@ -1837,7 +1837,7 @@ PQgetResult(PGconn *conn)
 			if (!res->events[i].proc(PGEVT_RESULTCREATE, &evt,
 									 res->events[i].passThrough))
 			{
-				printfPQExpBuffer(&conn->errorMessage,
+				appendPQExpBuffer(&conn->errorMessage,
 								  libpq_gettext("PGEventProc \"%s\" failed during PGEVT_RESULTCREATE event\n"),
 								  res->events[i].name);
 				pqSetResultError(res, conn->errorMessage.data);
@@ -2005,8 +2005,8 @@ PQexecStart(PGconn *conn)
 			else
 			{
 				/* In older protocols we have to punt */
-				printfPQExpBuffer(&conn->errorMessage,
-								  libpq_gettext("COPY IN state must be terminated first\n"));
+				appendPQExpBufferStr(&conn->errorMessage,
+									 libpq_gettext("COPY IN state must be terminated first\n"));
 				return false;
 			}
 		}
@@ -2025,16 +2025,16 @@ PQexecStart(PGconn *conn)
 			else
 			{
 				/* In older protocols we have to punt */
-				printfPQExpBuffer(&conn->errorMessage,
-								  libpq_gettext("COPY OUT state must be terminated first\n"));
+				appendPQExpBufferStr(&conn->errorMessage,
+									 libpq_gettext("COPY OUT state must be terminated first\n"));
 				return false;
 			}
 		}
 		else if (resultStatus == PGRES_COPY_BOTH)
 		{
 			/* We don't allow PQexec during COPY BOTH */
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("PQexec not allowed during COPY BOTH\n"));
+			appendPQExpBufferStr(&conn->errorMessage,
+								 libpq_gettext("PQexec not allowed during COPY BOTH\n"));
 			return false;
 		}
 		/* check for loss of connection, too */
@@ -2076,12 +2076,6 @@ PQexecFinish(PGconn *conn)
 				pqCatenateResultError(lastResult, result->errMsg);
 				PQclear(result);
 				result = lastResult;
-
-				/*
-				 * Make sure PQerrorMessage agrees with concatenated result
-				 */
-				resetPQExpBuffer(&conn->errorMessage);
-				appendPQExpBufferStr(&conn->errorMessage, result->errMsg);
 			}
 			else
 				PQclear(lastResult);
@@ -2187,8 +2181,8 @@ PQsendDescribe(PGconn *conn, char desc_type, const char *desc_target)
 	/* This isn't gonna work on a 2.0 server */
 	if (PG_PROTOCOL_MAJOR(conn->pversion) < 3)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("function requires at least protocol version 3.0\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("function requires at least protocol version 3.0\n"));
 		return 0;
 	}
 
@@ -2276,8 +2270,8 @@ PQputCopyData(PGconn *conn, const char *buffer, int nbytes)
 	if (conn->asyncStatus != PGASYNC_COPY_IN &&
 		conn->asyncStatus != PGASYNC_COPY_BOTH)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("no COPY in progress\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("no COPY in progress\n"));
 		return -1;
 	}
 
@@ -2343,8 +2337,8 @@ PQputCopyEnd(PGconn *conn, const char *errormsg)
 	if (conn->asyncStatus != PGASYNC_COPY_IN &&
 		conn->asyncStatus != PGASYNC_COPY_BOTH)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("no COPY in progress\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("no COPY in progress\n"));
 		return -1;
 	}
 
@@ -2386,8 +2380,8 @@ PQputCopyEnd(PGconn *conn, const char *errormsg)
 		if (errormsg)
 		{
 			/* Oops, no way to do this in 2.0 */
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("function requires at least protocol version 3.0\n"));
+			appendPQExpBufferStr(&conn->errorMessage,
+								 libpq_gettext("function requires at least protocol version 3.0\n"));
 			return -1;
 		}
 		else
@@ -2405,7 +2399,6 @@ PQputCopyEnd(PGconn *conn, const char *errormsg)
 		conn->asyncStatus = PGASYNC_COPY_OUT;
 	else
 		conn->asyncStatus = PGASYNC_BUSY;
-	resetPQExpBuffer(&conn->errorMessage);
 
 	/* Try to flush data */
 	if (pqFlush(conn) < 0)
@@ -2433,8 +2426,8 @@ PQgetCopyData(PGconn *conn, char **buffer, int async)
 	if (conn->asyncStatus != PGASYNC_COPY_OUT &&
 		conn->asyncStatus != PGASYNC_COPY_BOTH)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("no COPY in progress\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("no COPY in progress\n"));
 		return -2;
 	}
 	if (PG_PROTOCOL_MAJOR(conn->pversion) >= 3)
@@ -2617,14 +2610,14 @@ PQfn(PGconn *conn,
 	if (!conn)
 		return NULL;
 
-	/* clear the error string */
+	/* Clear the error string, like PQsendQueryStart() */
 	resetPQExpBuffer(&conn->errorMessage);
 
 	if (conn->sock == PGINVALID_SOCKET || conn->asyncStatus != PGASYNC_IDLE ||
 		conn->result != NULL)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("connection in wrong state\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("connection in wrong state\n"));
 		return NULL;
 	}
 
@@ -3343,8 +3336,8 @@ PQescapeStringInternal(PGconn *conn,
 			if (error)
 				*error = 1;
 			if (conn)
-				printfPQExpBuffer(&conn->errorMessage,
-								  libpq_gettext("incomplete multibyte character\n"));
+				appendPQExpBufferStr(&conn->errorMessage,
+									 libpq_gettext("incomplete multibyte character\n"));
 			for (; i < len; i++)
 			{
 				if (((size_t) (target - to)) / 2 >= length)
@@ -3427,8 +3420,8 @@ PQescapeInternal(PGconn *conn, const char *str, size_t len, bool as_ident)
 			/* Multibyte character overruns allowable length. */
 			if ((s - str) + charlen > len || memchr(s, 0, charlen) != NULL)
 			{
-				printfPQExpBuffer(&conn->errorMessage,
-								  libpq_gettext("incomplete multibyte character\n"));
+				appendPQExpBufferStr(&conn->errorMessage,
+									 libpq_gettext("incomplete multibyte character\n"));
 				return NULL;
 			}
 
@@ -3445,8 +3438,7 @@ PQescapeInternal(PGconn *conn, const char *str, size_t len, bool as_ident)
 	result = rp = (char *) malloc(result_size);
 	if (rp == NULL)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("out of memory\n"));
+		pqReportOOM(conn);
 		return NULL;
 	}
 
@@ -3610,8 +3602,7 @@ PQescapeByteaInternal(PGconn *conn,
 	if (rp == NULL)
 	{
 		if (conn)
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("out of memory\n"));
+			pqReportOOM(conn);
 		return NULL;
 	}
 
diff --git a/src/interfaces/libpq/fe-lobj.c b/src/interfaces/libpq/fe-lobj.c
index a5ad3af..9259551 100644
--- a/src/interfaces/libpq/fe-lobj.c
+++ b/src/interfaces/libpq/fe-lobj.c
@@ -61,7 +61,13 @@ lo_open(PGconn *conn, Oid lobjId, int mode)
 	PQArgBlock	argv[2];
 	PGresult   *res;
 
-	if (conn == NULL || conn->lobjfuncs == NULL)
+	if (conn == NULL)
+		return -1;
+
+	/* This is a library entry point, so start with an empty error message. */
+	resetPQExpBuffer(&conn->errorMessage);
+
+	if (conn->lobjfuncs == NULL)
 	{
 		if (lo_initialize(conn) < 0)
 			return -1;
@@ -103,7 +109,13 @@ lo_close(PGconn *conn, int fd)
 	int			retval;
 	int			result_len;
 
-	if (conn == NULL || conn->lobjfuncs == NULL)
+	if (conn == NULL)
+		return -1;
+
+	/* This is a library entry point, so start with an empty error message. */
+	resetPQExpBuffer(&conn->errorMessage);
+
+	if (conn->lobjfuncs == NULL)
 	{
 		if (lo_initialize(conn) < 0)
 			return -1;
@@ -141,7 +153,13 @@ lo_truncate(PGconn *conn, int fd, size_t len)
 	int			retval;
 	int			result_len;
 
-	if (conn == NULL || conn->lobjfuncs == NULL)
+	if (conn == NULL)
+		return -1;
+
+	/* This is a library entry point, so start with an empty error message. */
+	resetPQExpBuffer(&conn->errorMessage);
+
+	if (conn->lobjfuncs == NULL)
 	{
 		if (lo_initialize(conn) < 0)
 			return -1;
@@ -150,8 +168,8 @@ lo_truncate(PGconn *conn, int fd, size_t len)
 	/* Must check this on-the-fly because it's not there pre-8.3 */
 	if (conn->lobjfuncs->fn_lo_truncate == 0)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("cannot determine OID of function lo_truncate\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("cannot determine OID of function lo_truncate\n"));
 		return -1;
 	}
 
@@ -166,8 +184,8 @@ lo_truncate(PGconn *conn, int fd, size_t len)
 	 */
 	if (len > (size_t) INT_MAX)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("argument of lo_truncate exceeds integer range\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("argument of lo_truncate exceeds integer range\n"));
 		return -1;
 	}
 
@@ -209,7 +227,13 @@ lo_truncate64(PGconn *conn, int fd, pg_int64 len)
 	int			retval;
 	int			result_len;
 
-	if (conn == NULL || conn->lobjfuncs == NULL)
+	if (conn == NULL)
+		return -1;
+
+	/* This is a library entry point, so start with an empty error message. */
+	resetPQExpBuffer(&conn->errorMessage);
+
+	if (conn->lobjfuncs == NULL)
 	{
 		if (lo_initialize(conn) < 0)
 			return -1;
@@ -217,8 +241,8 @@ lo_truncate64(PGconn *conn, int fd, pg_int64 len)
 
 	if (conn->lobjfuncs->fn_lo_truncate64 == 0)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("cannot determine OID of function lo_truncate64\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("cannot determine OID of function lo_truncate64\n"));
 		return -1;
 	}
 
@@ -261,7 +285,13 @@ lo_read(PGconn *conn, int fd, char *buf, size_t len)
 	PGresult   *res;
 	int			result_len;
 
-	if (conn == NULL || conn->lobjfuncs == NULL)
+	if (conn == NULL)
+		return -1;
+
+	/* This is a library entry point, so start with an empty error message. */
+	resetPQExpBuffer(&conn->errorMessage);
+
+	if (conn->lobjfuncs == NULL)
 	{
 		if (lo_initialize(conn) < 0)
 			return -1;
@@ -275,8 +305,8 @@ lo_read(PGconn *conn, int fd, char *buf, size_t len)
 	 */
 	if (len > (size_t) INT_MAX)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("argument of lo_read exceeds integer range\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("argument of lo_read exceeds integer range\n"));
 		return -1;
 	}
 
@@ -316,7 +346,13 @@ lo_write(PGconn *conn, int fd, const char *buf, size_t len)
 	int			result_len;
 	int			retval;
 
-	if (conn == NULL || conn->lobjfuncs == NULL)
+	if (conn == NULL)
+		return -1;
+
+	/* This is a library entry point, so start with an empty error message. */
+	resetPQExpBuffer(&conn->errorMessage);
+
+	if (conn->lobjfuncs == NULL)
 	{
 		if (lo_initialize(conn) < 0)
 			return -1;
@@ -330,8 +366,8 @@ lo_write(PGconn *conn, int fd, const char *buf, size_t len)
 	 */
 	if (len > (size_t) INT_MAX)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("argument of lo_write exceeds integer range\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("argument of lo_write exceeds integer range\n"));
 		return -1;
 	}
 
@@ -369,7 +405,13 @@ lo_lseek(PGconn *conn, int fd, int offset, int whence)
 	int			retval;
 	int			result_len;
 
-	if (conn == NULL || conn->lobjfuncs == NULL)
+	if (conn == NULL)
+		return -1;
+
+	/* This is a library entry point, so start with an empty error message. */
+	resetPQExpBuffer(&conn->errorMessage);
+
+	if (conn->lobjfuncs == NULL)
 	{
 		if (lo_initialize(conn) < 0)
 			return -1;
@@ -413,7 +455,13 @@ lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence)
 	pg_int64	retval;
 	int			result_len;
 
-	if (conn == NULL || conn->lobjfuncs == NULL)
+	if (conn == NULL)
+		return -1;
+
+	/* This is a library entry point, so start with an empty error message. */
+	resetPQExpBuffer(&conn->errorMessage);
+
+	if (conn->lobjfuncs == NULL)
 	{
 		if (lo_initialize(conn) < 0)
 			return -1;
@@ -421,8 +469,8 @@ lo_lseek64(PGconn *conn, int fd, pg_int64 offset, int whence)
 
 	if (conn->lobjfuncs->fn_lo_lseek64 == 0)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("cannot determine OID of function lo_lseek64\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("cannot determine OID of function lo_lseek64\n"));
 		return -1;
 	}
 
@@ -469,7 +517,13 @@ lo_creat(PGconn *conn, int mode)
 	int			retval;
 	int			result_len;
 
-	if (conn == NULL || conn->lobjfuncs == NULL)
+	if (conn == NULL)
+		return InvalidOid;
+
+	/* This is a library entry point, so start with an empty error message. */
+	resetPQExpBuffer(&conn->errorMessage);
+
+	if (conn->lobjfuncs == NULL)
 	{
 		if (lo_initialize(conn) < 0)
 			return InvalidOid;
@@ -508,7 +562,13 @@ lo_create(PGconn *conn, Oid lobjId)
 	int			retval;
 	int			result_len;
 
-	if (conn == NULL || conn->lobjfuncs == NULL)
+	if (conn == NULL)
+		return InvalidOid;
+
+	/* This is a library entry point, so start with an empty error message. */
+	resetPQExpBuffer(&conn->errorMessage);
+
+	if (conn->lobjfuncs == NULL)
 	{
 		if (lo_initialize(conn) < 0)
 			return InvalidOid;
@@ -517,8 +577,8 @@ lo_create(PGconn *conn, Oid lobjId)
 	/* Must check this on-the-fly because it's not there pre-8.1 */
 	if (conn->lobjfuncs->fn_lo_create == 0)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("cannot determine OID of function lo_create\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("cannot determine OID of function lo_create\n"));
 		return InvalidOid;
 	}
 
@@ -552,7 +612,13 @@ lo_tell(PGconn *conn, int fd)
 	PGresult   *res;
 	int			result_len;
 
-	if (conn == NULL || conn->lobjfuncs == NULL)
+	if (conn == NULL)
+		return -1;
+
+	/* This is a library entry point, so start with an empty error message. */
+	resetPQExpBuffer(&conn->errorMessage);
+
+	if (conn->lobjfuncs == NULL)
 	{
 		if (lo_initialize(conn) < 0)
 			return -1;
@@ -588,7 +654,13 @@ lo_tell64(PGconn *conn, int fd)
 	PGresult   *res;
 	int			result_len;
 
-	if (conn == NULL || conn->lobjfuncs == NULL)
+	if (conn == NULL)
+		return -1;
+
+	/* This is a library entry point, so start with an empty error message. */
+	resetPQExpBuffer(&conn->errorMessage);
+
+	if (conn->lobjfuncs == NULL)
 	{
 		if (lo_initialize(conn) < 0)
 			return -1;
@@ -596,8 +668,8 @@ lo_tell64(PGconn *conn, int fd)
 
 	if (conn->lobjfuncs->fn_lo_tell64 == 0)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("cannot determine OID of function lo_tell64\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("cannot determine OID of function lo_tell64\n"));
 		return -1;
 	}
 
@@ -632,7 +704,13 @@ lo_unlink(PGconn *conn, Oid lobjId)
 	int			result_len;
 	int			retval;
 
-	if (conn == NULL || conn->lobjfuncs == NULL)
+	if (conn == NULL)
+		return -1;
+
+	/* This is a library entry point, so start with an empty error message. */
+	resetPQExpBuffer(&conn->errorMessage);
+
+	if (conn->lobjfuncs == NULL)
 	{
 		if (lo_initialize(conn) < 0)
 			return -1;
@@ -702,7 +780,7 @@ lo_import_internal(PGconn *conn, const char *filename, Oid oid)
 	fd = open(filename, O_RDONLY | PG_BINARY, 0666);
 	if (fd < 0)
 	{							/* error */
-		printfPQExpBuffer(&conn->errorMessage,
+		appendPQExpBuffer(&conn->errorMessage,
 						  libpq_gettext("could not open file \"%s\": %s\n"),
 						  filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
 		return InvalidOid;
@@ -757,7 +835,9 @@ lo_import_internal(PGconn *conn, const char *filename, Oid oid)
 
 		(void) lo_close(conn, lobj);
 		(void) close(fd);
-		printfPQExpBuffer(&conn->errorMessage,
+		/* Lose any error message reported by lo_close */
+		resetPQExpBuffer(&conn->errorMessage);
+		appendPQExpBuffer(&conn->errorMessage,
 						  libpq_gettext("could not read from file \"%s\": %s\n"),
 						  filename,
 						  pqStrerror(save_errno, sebuf, sizeof(sebuf)));
@@ -811,7 +891,9 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
 		int			save_errno = errno;
 
 		(void) lo_close(conn, lobj);
-		printfPQExpBuffer(&conn->errorMessage,
+		/* Lose any error message reported by lo_close */
+		resetPQExpBuffer(&conn->errorMessage);
+		appendPQExpBuffer(&conn->errorMessage,
 						  libpq_gettext("could not open file \"%s\": %s\n"),
 						  filename,
 						  pqStrerror(save_errno, sebuf, sizeof(sebuf)));
@@ -831,7 +913,9 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
 
 			(void) lo_close(conn, lobj);
 			(void) close(fd);
-			printfPQExpBuffer(&conn->errorMessage,
+			/* Lose any error message reported by lo_close */
+			resetPQExpBuffer(&conn->errorMessage);
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("could not write to file \"%s\": %s\n"),
 							  filename,
 							  pqStrerror(save_errno, sebuf, sizeof(sebuf)));
@@ -852,10 +936,10 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
 		result = -1;
 	}
 
-	/* if we already failed, don't overwrite that msg with a close error */
+	/* if we already failed, we don't need an additional error from close() */
 	if (close(fd) && result >= 0)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
+		appendPQExpBuffer(&conn->errorMessage,
 						  libpq_gettext("could not write to file \"%s\": %s\n"),
 						  filename, pqStrerror(errno, sebuf, sizeof(sebuf)));
 		result = -1;
@@ -882,17 +966,13 @@ lo_initialize(PGconn *conn)
 	const char *fname;
 	Oid			foid;
 
-	if (!conn)
-		return -1;
-
 	/*
 	 * Allocate the structure to hold the functions OID's
 	 */
 	lobjfuncs = (PGlobjfuncs *) malloc(sizeof(PGlobjfuncs));
 	if (lobjfuncs == NULL)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("out of memory\n"));
+		pqReportOOM(conn);
 		return -1;
 	}
 	MemSet((char *) lobjfuncs, 0, sizeof(PGlobjfuncs));
@@ -931,6 +1011,7 @@ lo_initialize(PGconn *conn)
 			"or proname = 'loread' "
 			"or proname = 'lowrite'";
 
+	/* PQexec will reset errorMessage, but that's OK */
 	res = PQexec(conn, query);
 	if (res == NULL)
 	{
@@ -942,8 +1023,8 @@ lo_initialize(PGconn *conn)
 	{
 		free(lobjfuncs);
 		PQclear(res);
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("query to initialize large object functions did not return data\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("query to initialize large object functions did not return data\n"));
 		return -1;
 	}
 
@@ -991,57 +1072,57 @@ lo_initialize(PGconn *conn)
 	 */
 	if (lobjfuncs->fn_lo_open == 0)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("cannot determine OID of function lo_open\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("cannot determine OID of function lo_open\n"));
 		free(lobjfuncs);
 		return -1;
 	}
 	if (lobjfuncs->fn_lo_close == 0)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("cannot determine OID of function lo_close\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("cannot determine OID of function lo_close\n"));
 		free(lobjfuncs);
 		return -1;
 	}
 	if (lobjfuncs->fn_lo_creat == 0)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("cannot determine OID of function lo_creat\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("cannot determine OID of function lo_creat\n"));
 		free(lobjfuncs);
 		return -1;
 	}
 	if (lobjfuncs->fn_lo_unlink == 0)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("cannot determine OID of function lo_unlink\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("cannot determine OID of function lo_unlink\n"));
 		free(lobjfuncs);
 		return -1;
 	}
 	if (lobjfuncs->fn_lo_lseek == 0)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("cannot determine OID of function lo_lseek\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("cannot determine OID of function lo_lseek\n"));
 		free(lobjfuncs);
 		return -1;
 	}
 	if (lobjfuncs->fn_lo_tell == 0)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("cannot determine OID of function lo_tell\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("cannot determine OID of function lo_tell\n"));
 		free(lobjfuncs);
 		return -1;
 	}
 	if (lobjfuncs->fn_lo_read == 0)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("cannot determine OID of function loread\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("cannot determine OID of function loread\n"));
 		free(lobjfuncs);
 		return -1;
 	}
 	if (lobjfuncs->fn_lo_write == 0)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("cannot determine OID of function lowrite\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("cannot determine OID of function lowrite\n"));
 		free(lobjfuncs);
 		return -1;
 	}
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c
index 2a6637f..81bbb8c 100644
--- a/src/interfaces/libpq/fe-misc.c
+++ b/src/interfaces/libpq/fe-misc.c
@@ -393,8 +393,7 @@ pqCheckOutBufferSpace(size_t bytes_needed, PGconn *conn)
 	}
 
 	/* realloc failed. Probably out of memory */
-	printfPQExpBuffer(&conn->errorMessage,
-					  "cannot allocate memory for output buffer\n");
+	pqReportOOM(conn);
 	return EOF;
 }
 
@@ -487,8 +486,7 @@ pqCheckInBufferSpace(size_t bytes_needed, PGconn *conn)
 	}
 
 	/* realloc failed. Probably out of memory */
-	printfPQExpBuffer(&conn->errorMessage,
-					  "cannot allocate memory for input buffer\n");
+	pqReportOOM(conn);
 	return EOF;
 }
 
@@ -633,8 +631,8 @@ pqReadData(PGconn *conn)
 
 	if (conn->sock == PGINVALID_SOCKET)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("connection not open\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("connection not open\n"));
 		return -1;
 	}
 
@@ -802,11 +800,10 @@ retry4:
 	 * means the connection has been closed.  Cope.
 	 */
 definitelyEOF:
-	printfPQExpBuffer(&conn->errorMessage,
-					  libpq_gettext(
-									"server closed the connection unexpectedly\n"
-									"\tThis probably means the server terminated abnormally\n"
-									"\tbefore or while processing the request.\n"));
+	appendPQExpBufferStr(&conn->errorMessage,
+						 libpq_gettext("server closed the connection unexpectedly\n"
+									   "\tThis probably means the server terminated abnormally\n"
+									   "\tbefore or while processing the request.\n"));
 
 	/* Come here if lower-level code already set a suitable errorMessage */
 definitelyFailed:
@@ -834,8 +831,8 @@ pqSendSome(PGconn *conn, int len)
 
 	if (conn->sock == PGINVALID_SOCKET)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("connection not open\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("connection not open\n"));
 		/* Discard queued data; no chance it'll ever be sent */
 		conn->outCount = 0;
 		return -1;
@@ -1005,8 +1002,8 @@ pqWaitTimed(int forRead, int forWrite, PGconn *conn, time_t finish_time)
 
 	if (result == 0)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("timeout expired\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("timeout expired\n"));
 		return 1;
 	}
 
@@ -1050,8 +1047,8 @@ pqSocketCheck(PGconn *conn, int forRead, int forWrite, time_t end_time)
 		return -1;
 	if (conn->sock == PGINVALID_SOCKET)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("invalid socket\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("invalid socket\n"));
 		return -1;
 	}
 
@@ -1073,7 +1070,7 @@ pqSocketCheck(PGconn *conn, int forRead, int forWrite, time_t end_time)
 	{
 		char		sebuf[256];
 
-		printfPQExpBuffer(&conn->errorMessage,
+		appendPQExpBuffer(&conn->errorMessage,
 						  libpq_gettext("select() failed: %s\n"),
 						  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
 	}
@@ -1211,11 +1208,49 @@ PQenv2encoding(void)
 	return encoding;
 }
 
+/*
+ * Report an out-of-memory error by appending a message to conn->errorMessage.
+ *
+ * This task is just common enough, and nontrivial enough, to deserve its own
+ * subroutine.
+ */
+void
+pqReportOOM(PGconn *conn)
+{
+	pqReportOOMBuffer(&conn->errorMessage);
+}
+
+/*
+ * As above, but work with a bare error-message-buffer pointer.
+ */
+void
+pqReportOOMBuffer(PQExpBuffer errorMessage)
+{
+	const char *msg = libpq_gettext("out of memory\n");
+
+	/*
+	 * First just try to append the message.  Even though we're up against
+	 * OOM, this is likely to succeed because of unused space within
+	 * errorMessage's buffer.
+	 */
+	appendPQExpBufferStr(errorMessage, msg);
+
+	/*
+	 * If that didn't succeed, it'll have marked the buffer broken.  Our
+	 * fallback plan is to reset the buffer (hopefully regaining some space)
+	 * and try again.  If still no luck, not much we can do.
+	 */
+	if (PQExpBufferBroken(errorMessage))
+	{
+		resetPQExpBuffer(errorMessage);
+		appendPQExpBufferStr(errorMessage, msg);
+	}
+}
 
 #ifdef ENABLE_NLS
 
 static void
-libpq_binddomain()
+libpq_binddomain(void)
 {
 	static bool already_bound = false;
 
diff --git a/src/interfaces/libpq/fe-protocol2.c b/src/interfaces/libpq/fe-protocol2.c
index 53e5083..04a2e47 100644
--- a/src/interfaces/libpq/fe-protocol2.c
+++ b/src/interfaces/libpq/fe-protocol2.c
@@ -85,11 +85,9 @@ pqSetenvPoll(PGconn *conn)
 			return PGRES_POLLING_OK;
 
 		default:
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext(
-											"invalid setenv state %c, "
-											"probably indicative of memory corruption\n"
-											),
+			appendPQExpBuffer(&conn->errorMessage,
+							  libpq_gettext("invalid setenv state %c, "
+											"probably indicative of memory corruption\n"),
 							  conn->setenv_state);
 			goto error_return;
 	}
@@ -385,7 +383,7 @@ pqSetenvPoll(PGconn *conn)
 				}
 
 			default:
-				printfPQExpBuffer(&conn->errorMessage,
+				appendPQExpBuffer(&conn->errorMessage,
 								  libpq_gettext("invalid state %c, "
 												"probably indicative of memory corruption\n"),
 								  conn->setenv_state);
@@ -498,8 +496,7 @@ pqParseInput2(PGconn *conn)
 														   PGRES_COMMAND_OK);
 						if (!conn->result)
 						{
-							printfPQExpBuffer(&conn->errorMessage,
-											  libpq_gettext("out of memory"));
+							pqReportOOM(conn);
 							pqSaveErrorResult(conn);
 						}
 					}
@@ -533,8 +530,7 @@ pqParseInput2(PGconn *conn)
 														   PGRES_EMPTY_QUERY);
 						if (!conn->result)
 						{
-							printfPQExpBuffer(&conn->errorMessage,
-											  libpq_gettext("out of memory"));
+							pqReportOOM(conn);
 							pqSaveErrorResult(conn);
 						}
 					}
@@ -627,9 +623,8 @@ pqParseInput2(PGconn *conn)
 					 * never arrives from the server during protocol 2.0.
 					 */
 				default:
-					printfPQExpBuffer(&conn->errorMessage,
-									  libpq_gettext(
-													"unexpected response from server; first received character was \"%c\"\n"),
+					appendPQExpBuffer(&conn->errorMessage,
+									  libpq_gettext("unexpected response from server; first received character was \"%c\"\n"),
 									  id);
 					/* build an error result holding the error message */
 					pqSaveErrorResult(conn);
@@ -760,7 +755,7 @@ advance_and_error:
 	if (!errmsg)
 		errmsg = libpq_gettext("out of memory for query result");
 
-	printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
+	appendPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
 
 	/*
 	 * XXX: if PQmakeEmptyPGresult() fails, there's probably not much we can
@@ -935,7 +930,7 @@ set_error_result:
 	if (!errmsg)
 		errmsg = libpq_gettext("out of memory for query result");
 
-	printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
+	appendPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
 
 	/*
 	 * XXX: if PQmakeEmptyPGresult() fails, there's probably not much we can
@@ -1048,12 +1043,10 @@ pqGetErrorNotice2(PGconn *conn, bool isError)
 	{
 		pqClearAsyncResult(conn);	/* redundant, but be safe */
 		conn->result = res;
-		resetPQExpBuffer(&conn->errorMessage);
 		if (res && !PQExpBufferDataBroken(workBuf) && res->errMsg)
 			appendPQExpBufferStr(&conn->errorMessage, res->errMsg);
 		else
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("out of memory"));
+			pqReportOOM(conn);
 		if (conn->xactStatus == PQTRANS_INTRANS)
 			conn->xactStatus = PQTRANS_INERROR;
 	}
@@ -1209,8 +1202,7 @@ pqGetCopyData2(PGconn *conn, char **buffer, int async)
 		*buffer = (char *) malloc(msgLength + 1);
 		if (*buffer == NULL)
 		{
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("out of memory\n"));
+			pqReportOOM(conn);
 			return -2;
 		}
 		memcpy(*buffer, &conn->inBuffer[conn->inStart], msgLength);
@@ -1355,8 +1347,8 @@ pqEndcopy2(PGconn *conn)
 	if (conn->asyncStatus != PGASYNC_COPY_IN &&
 		conn->asyncStatus != PGASYNC_COPY_OUT)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("no COPY in progress\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("no COPY in progress\n"));
 		return 1;
 	}
 
@@ -1373,7 +1365,6 @@ pqEndcopy2(PGconn *conn)
 
 	/* Return to active duty */
 	conn->asyncStatus = PGASYNC_BUSY;
-	resetPQExpBuffer(&conn->errorMessage);
 
 	/* Wait for the completion response */
 	result = PQgetResult(conn);
@@ -1544,7 +1535,7 @@ pqFunctionCall2(PGconn *conn, Oid fnid,
 				else
 				{
 					/* The backend violates the protocol. */
-					printfPQExpBuffer(&conn->errorMessage,
+					appendPQExpBuffer(&conn->errorMessage,
 									  libpq_gettext("protocol error: id=0x%x\n"),
 									  id);
 					pqSaveErrorResult(conn);
@@ -1576,7 +1567,7 @@ pqFunctionCall2(PGconn *conn, Oid fnid,
 				return PQmakeEmptyPGresult(conn, status);
 			default:
 				/* The backend violates the protocol. */
-				printfPQExpBuffer(&conn->errorMessage,
+				appendPQExpBuffer(&conn->errorMessage,
 								  libpq_gettext("protocol error: id=0x%x\n"),
 								  id);
 				pqSaveErrorResult(conn);
diff --git a/src/interfaces/libpq/fe-protocol3.c b/src/interfaces/libpq/fe-protocol3.c
index 8345faf..98261d4 100644
--- a/src/interfaces/libpq/fe-protocol3.c
+++ b/src/interfaces/libpq/fe-protocol3.c
@@ -204,8 +204,7 @@ pqParseInput3(PGconn *conn)
 														   PGRES_COMMAND_OK);
 						if (!conn->result)
 						{
-							printfPQExpBuffer(&conn->errorMessage,
-											  libpq_gettext("out of memory"));
+							pqReportOOM(conn);
 							pqSaveErrorResult(conn);
 						}
 					}
@@ -231,8 +230,7 @@ pqParseInput3(PGconn *conn)
 														   PGRES_EMPTY_QUERY);
 						if (!conn->result)
 						{
-							printfPQExpBuffer(&conn->errorMessage,
-											  libpq_gettext("out of memory"));
+							pqReportOOM(conn);
 							pqSaveErrorResult(conn);
 						}
 					}
@@ -248,8 +246,7 @@ pqParseInput3(PGconn *conn)
 															   PGRES_COMMAND_OK);
 							if (!conn->result)
 							{
-								printfPQExpBuffer(&conn->errorMessage,
-												  libpq_gettext("out of memory"));
+								pqReportOOM(conn);
 								pqSaveErrorResult(conn);
 							}
 						}
@@ -328,8 +325,7 @@ pqParseInput3(PGconn *conn)
 															   PGRES_COMMAND_OK);
 							if (!conn->result)
 							{
-								printfPQExpBuffer(&conn->errorMessage,
-												  libpq_gettext("out of memory"));
+								pqReportOOM(conn);
 								pqSaveErrorResult(conn);
 							}
 						}
@@ -363,8 +359,8 @@ pqParseInput3(PGconn *conn)
 					else
 					{
 						/* Set up to report error at end of query */
-						printfPQExpBuffer(&conn->errorMessage,
-										  libpq_gettext("server sent data (\"D\" message) without prior row description (\"T\" message)\n"));
+						appendPQExpBufferStr(&conn->errorMessage,
+											 libpq_gettext("server sent data (\"D\" message) without prior row description (\"T\" message)\n"));
 						pqSaveErrorResult(conn);
 						/* Discard the unexpected message */
 						conn->inCursor += msgLength;
@@ -406,9 +402,8 @@ pqParseInput3(PGconn *conn)
 					 */
 					break;
 				default:
-					printfPQExpBuffer(&conn->errorMessage,
-									  libpq_gettext(
-													"unexpected response from server; first received character was \"%c\"\n"),
+					appendPQExpBuffer(&conn->errorMessage,
+									  libpq_gettext("unexpected response from server; first received character was \"%c\"\n"),
 									  id);
 					/* build an error result holding the error message */
 					pqSaveErrorResult(conn);
@@ -428,7 +423,7 @@ pqParseInput3(PGconn *conn)
 		else
 		{
 			/* Trouble --- report it */
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("message contents do not agree with length in message type \"%c\"\n"),
 							  id);
 			/* build an error result holding the error message */
@@ -448,9 +443,8 @@ pqParseInput3(PGconn *conn)
 static void
 handleSyncLoss(PGconn *conn, char id, int msgLength)
 {
-	printfPQExpBuffer(&conn->errorMessage,
-					  libpq_gettext(
-									"lost synchronization with server: got message type \"%c\", length %d\n"),
+	appendPQExpBuffer(&conn->errorMessage,
+					  libpq_gettext("lost synchronization with server: got message type \"%c\", length %d\n"),
 					  id, msgLength);
 	/* build an error result holding the error message */
 	pqSaveErrorResult(conn);
@@ -625,7 +619,7 @@ advance_and_error:
 	if (!errmsg)
 		errmsg = libpq_gettext("out of memory for query result");
 
-	printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
+	appendPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
 	pqSaveErrorResult(conn);
 
 	/*
@@ -725,7 +719,7 @@ advance_and_error:
 	 */
 	if (!errmsg)
 		errmsg = libpq_gettext("out of memory");
-	printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
+	appendPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
 	pqSaveErrorResult(conn);
 
 	/*
@@ -852,7 +846,7 @@ set_error_result:
 	if (!errmsg)
 		errmsg = libpq_gettext("out of memory for query result");
 
-	printfPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
+	appendPQExpBuffer(&conn->errorMessage, "%s\n", errmsg);
 	pqSaveErrorResult(conn);
 
 	/*
@@ -953,9 +947,10 @@ pqGetErrorNotice3(PGconn *conn, bool isError)
 			res->errMsg = pqResultStrdup(res, workBuf.data);
 		pqClearAsyncResult(conn);	/* redundant, but be safe */
 		conn->result = res;
+
+		/* We also keep a running history of errors in conn->errorMessage. */
 		if (PQExpBufferDataBroken(workBuf))
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("out of memory"));
+			pqReportOOM(conn);
 		else
 			appendPQExpBufferStr(&conn->errorMessage, workBuf.data);
 	}
@@ -1681,8 +1676,7 @@ pqGetCopyData3(PGconn *conn, char **buffer, int async)
 			*buffer = (char *) malloc(msgLength + 1);
 			if (*buffer == NULL)
 			{
-				printfPQExpBuffer(&conn->errorMessage,
-								  libpq_gettext("out of memory\n"));
+				pqReportOOM(conn);
 				return -2;
 			}
 			memcpy(*buffer, &conn->inBuffer[conn->inCursor], msgLength);
@@ -1714,8 +1708,8 @@ pqGetline3(PGconn *conn, char *s, int maxlen)
 		 conn->asyncStatus != PGASYNC_COPY_BOTH) ||
 		conn->copy_is_binary)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("PQgetline: not doing text COPY OUT\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("PQgetline: not doing text COPY OUT\n"));
 		*s = '\0';
 		return EOF;
 	}
@@ -1820,8 +1814,8 @@ pqEndcopy3(PGconn *conn)
 		conn->asyncStatus != PGASYNC_COPY_OUT &&
 		conn->asyncStatus != PGASYNC_COPY_BOTH)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("no COPY in progress\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("no COPY in progress\n"));
 		return 1;
 	}
 
@@ -1854,7 +1848,6 @@ pqEndcopy3(PGconn *conn)
 
 	/* Return to active duty */
 	conn->asyncStatus = PGASYNC_BUSY;
-	resetPQExpBuffer(&conn->errorMessage);
 
 	/*
 	 * Non blocking connections may have to abort at this point.  If everyone
@@ -2092,7 +2085,7 @@ pqFunctionCall3(PGconn *conn, Oid fnid,
 				break;
 			default:
 				/* The backend violates the protocol. */
-				printfPQExpBuffer(&conn->errorMessage,
+				appendPQExpBuffer(&conn->errorMessage,
 								  libpq_gettext("protocol error: id=0x%x\n"),
 								  id);
 				pqSaveErrorResult(conn);
diff --git a/src/interfaces/libpq/fe-secure-common.c b/src/interfaces/libpq/fe-secure-common.c
index b3f580f..2bea0d2 100644
--- a/src/interfaces/libpq/fe-secure-common.c
+++ b/src/interfaces/libpq/fe-secure-common.c
@@ -94,8 +94,8 @@ pq_verify_peer_name_matches_certificate_name(PGconn *conn,
 
 	if (!(host && host[0] != '\0'))
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("host name must be specified\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("host name must be specified\n"));
 		return -1;
 	}
 
@@ -106,8 +106,7 @@ pq_verify_peer_name_matches_certificate_name(PGconn *conn,
 	name = malloc(namelen + 1);
 	if (name == NULL)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("out of memory\n"));
+		pqReportOOM(conn);
 		return -1;
 	}
 	memcpy(name, namedata, namelen);
@@ -120,8 +119,8 @@ pq_verify_peer_name_matches_certificate_name(PGconn *conn,
 	if (namelen != strlen(name))
 	{
 		free(name);
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("SSL certificate's name contains embedded null\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("SSL certificate's name contains embedded null\n"));
 		return -1;
 	}
 
@@ -167,8 +166,8 @@ pq_verify_peer_name_matches_certificate(PGconn *conn)
 	/* Check that we have a hostname to compare with. */
 	if (!(host && host[0] != '\0'))
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("host name must be specified for a verified SSL connection\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("host name must be specified for a verified SSL connection\n"));
 		return false;
 	}
 
@@ -184,7 +183,7 @@ pq_verify_peer_name_matches_certificate(PGconn *conn)
 		 */
 		if (names_examined > 1)
 		{
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_ngettext("server certificate for \"%s\" (and %d other name) does not match host name \"%s\"\n",
 											 "server certificate for \"%s\" (and %d other names) does not match host name \"%s\"\n",
 											 names_examined - 1),
@@ -192,14 +191,14 @@ pq_verify_peer_name_matches_certificate(PGconn *conn)
 		}
 		else if (names_examined == 1)
 		{
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("server certificate for \"%s\" does not match host name \"%s\"\n"),
 							  first_name, host);
 		}
 		else
 		{
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("could not get server's host name from server certificate\n"));
+			appendPQExpBufferStr(&conn->errorMessage,
+								 libpq_gettext("could not get server's host name from server certificate\n"));
 		}
 	}
 
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index bbae8ef..2cf3e22 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -177,8 +177,8 @@ rloop:
 			if (n < 0)
 			{
 				/* Not supposed to happen, so we don't translate the msg */
-				printfPQExpBuffer(&conn->errorMessage,
-								  "SSL_read failed but did not provide error information\n");
+				appendPQExpBufferStr(&conn->errorMessage,
+									 "SSL_read failed but did not provide error information\n");
 				/* assume the connection is broken */
 				result_errno = ECONNRESET;
 			}
@@ -201,21 +201,20 @@ rloop:
 				result_errno = SOCK_ERRNO;
 				if (result_errno == EPIPE ||
 					result_errno == ECONNRESET)
-					printfPQExpBuffer(&conn->errorMessage,
-									  libpq_gettext(
-													"server closed the connection unexpectedly\n"
-													"\tThis probably means the server terminated abnormally\n"
-													"\tbefore or while processing the request.\n"));
+					appendPQExpBufferStr(&conn->errorMessage,
+										 libpq_gettext("server closed the connection unexpectedly\n"
+													   "\tThis probably means the server terminated abnormally\n"
+													   "\tbefore or while processing the request.\n"));
 				else
-					printfPQExpBuffer(&conn->errorMessage,
+					appendPQExpBuffer(&conn->errorMessage,
 									  libpq_gettext("SSL SYSCALL error: %s\n"),
 									  SOCK_STRERROR(result_errno,
 													sebuf, sizeof(sebuf)));
 			}
 			else
 			{
-				printfPQExpBuffer(&conn->errorMessage,
-								  libpq_gettext("SSL SYSCALL error: EOF detected\n"));
+				appendPQExpBufferStr(&conn->errorMessage,
+									 libpq_gettext("SSL SYSCALL error: EOF detected\n"));
 				/* assume the connection is broken */
 				result_errno = ECONNRESET;
 				n = -1;
@@ -225,7 +224,7 @@ rloop:
 			{
 				char	   *errm = SSLerrmessage(ecode);
 
-				printfPQExpBuffer(&conn->errorMessage,
+				appendPQExpBuffer(&conn->errorMessage,
 								  libpq_gettext("SSL error: %s\n"), errm);
 				SSLerrfree(errm);
 				/* assume the connection is broken */
@@ -240,13 +239,13 @@ rloop:
 			 * a clean connection closure, so we should not report it as a
 			 * server crash.
 			 */
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("SSL connection has been closed unexpectedly\n"));
+			appendPQExpBufferStr(&conn->errorMessage,
+								 libpq_gettext("SSL connection has been closed unexpectedly\n"));
 			result_errno = ECONNRESET;
 			n = -1;
 			break;
 		default:
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("unrecognized SSL error code: %d\n"),
 							  err);
 			/* assume the connection is broken */
@@ -287,8 +286,8 @@ pgtls_write(PGconn *conn, const void *ptr, size_t len)
 			if (n < 0)
 			{
 				/* Not supposed to happen, so we don't translate the msg */
-				printfPQExpBuffer(&conn->errorMessage,
-								  "SSL_write failed but did not provide error information\n");
+				appendPQExpBufferStr(&conn->errorMessage,
+									 "SSL_write failed but did not provide error information\n");
 				/* assume the connection is broken */
 				result_errno = ECONNRESET;
 			}
@@ -309,21 +308,20 @@ pgtls_write(PGconn *conn, const void *ptr, size_t len)
 			{
 				result_errno = SOCK_ERRNO;
 				if (result_errno == EPIPE || result_errno == ECONNRESET)
-					printfPQExpBuffer(&conn->errorMessage,
-									  libpq_gettext(
-													"server closed the connection unexpectedly\n"
-													"\tThis probably means the server terminated abnormally\n"
-													"\tbefore or while processing the request.\n"));
+					appendPQExpBufferStr(&conn->errorMessage,
+										 libpq_gettext("server closed the connection unexpectedly\n"
+													   "\tThis probably means the server terminated abnormally\n"
+													   "\tbefore or while processing the request.\n"));
 				else
-					printfPQExpBuffer(&conn->errorMessage,
+					appendPQExpBuffer(&conn->errorMessage,
 									  libpq_gettext("SSL SYSCALL error: %s\n"),
 									  SOCK_STRERROR(result_errno,
 													sebuf, sizeof(sebuf)));
 			}
 			else
 			{
-				printfPQExpBuffer(&conn->errorMessage,
-								  libpq_gettext("SSL SYSCALL error: EOF detected\n"));
+				appendPQExpBufferStr(&conn->errorMessage,
+									 libpq_gettext("SSL SYSCALL error: EOF detected\n"));
 				/* assume the connection is broken */
 				result_errno = ECONNRESET;
 				n = -1;
@@ -333,7 +331,7 @@ pgtls_write(PGconn *conn, const void *ptr, size_t len)
 			{
 				char	   *errm = SSLerrmessage(ecode);
 
-				printfPQExpBuffer(&conn->errorMessage,
+				appendPQExpBuffer(&conn->errorMessage,
 								  libpq_gettext("SSL error: %s\n"), errm);
 				SSLerrfree(errm);
 				/* assume the connection is broken */
@@ -348,13 +346,13 @@ pgtls_write(PGconn *conn, const void *ptr, size_t len)
 			 * a clean connection closure, so we should not report it as a
 			 * server crash.
 			 */
-			printfPQExpBuffer(&conn->errorMessage,
-							  libpq_gettext("SSL connection has been closed unexpectedly\n"));
+			appendPQExpBufferStr(&conn->errorMessage,
+								 libpq_gettext("SSL connection has been closed unexpectedly\n"));
 			result_errno = ECONNRESET;
 			n = -1;
 			break;
 		default:
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("unrecognized SSL error code: %d\n"),
 							  err);
 			/* assume the connection is broken */
@@ -394,8 +392,8 @@ pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len)
 	if (!OBJ_find_sigid_algs(X509_get_signature_nid(peer_cert),
 							 &algo_nid, NULL))
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("could not determine server certificate signature algorithm\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("could not determine server certificate signature algorithm\n"));
 		return NULL;
 	}
 
@@ -415,7 +413,7 @@ pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len)
 			algo_type = EVP_get_digestbynid(algo_nid);
 			if (algo_type == NULL)
 			{
-				printfPQExpBuffer(&conn->errorMessage,
+				appendPQExpBuffer(&conn->errorMessage,
 								  libpq_gettext("could not find digest for NID %s\n"),
 								  OBJ_nid2sn(algo_nid));
 				return NULL;
@@ -425,8 +423,8 @@ pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len)
 
 	if (!X509_digest(peer_cert, algo_type, hash, &hash_size))
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("could not generate peer certificate hash\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("could not generate peer certificate hash\n"));
 		return NULL;
 	}
 
@@ -434,8 +432,7 @@ pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len)
 	cert_hash = malloc(hash_size);
 	if (cert_hash == NULL)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("out of memory\n"));
+		pqReportOOM(conn);
 		return NULL;
 	}
 	memcpy(cert_hash, hash, hash_size);
@@ -443,7 +440,7 @@ pgtls_get_peer_certificate_hash(PGconn *conn, size_t *len)
 
 	return cert_hash;
 }
-#endif /* HAVE_X509_GET_SIGNATURE_NID */
+#endif							/* HAVE_X509_GET_SIGNATURE_NID */
 
 /* ------------------------------------------------------------ */
 /*						OpenSSL specific code					*/
@@ -482,8 +479,8 @@ openssl_verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *nam
 	/* Should not happen... */
 	if (name_entry == NULL)
 	{
-		printfPQExpBuffer(&conn->errorMessage,
-						  libpq_gettext("SSL certificate's name entry is missing\n"));
+		appendPQExpBufferStr(&conn->errorMessage,
+							 libpq_gettext("SSL certificate's name entry is missing\n"));
 		return -1;
 	}
 
@@ -811,7 +808,7 @@ initialize_SSL(PGconn *conn)
 	{
 		char	   *err = SSLerrmessage(ERR_get_error());
 
-		printfPQExpBuffer(&conn->errorMessage,
+		appendPQExpBuffer(&conn->errorMessage,
 						  libpq_gettext("could not create SSL context: %s\n"),
 						  err);
 		SSLerrfree(err);
@@ -848,7 +845,7 @@ initialize_SSL(PGconn *conn)
 		{
 			char	   *err = SSLerrmessage(ERR_get_error());
 
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("could not read root certificate file \"%s\": %s\n"),
 							  fnbuf, err);
 			SSLerrfree(err);
@@ -876,7 +873,7 @@ initialize_SSL(PGconn *conn)
 #else
 				char	   *err = SSLerrmessage(ERR_get_error());
 
-				printfPQExpBuffer(&conn->errorMessage,
+				appendPQExpBuffer(&conn->errorMessage,
 								  libpq_gettext("SSL library does not support CRL certificates (file \"%s\")\n"),
 								  fnbuf);
 				SSLerrfree(err);
@@ -904,11 +901,11 @@ initialize_SSL(PGconn *conn)
 			 * that it seems worth having a specialized error message for it.
 			 */
 			if (fnbuf[0] == '\0')
-				printfPQExpBuffer(&conn->errorMessage,
-								  libpq_gettext("could not get home directory to locate root certificate file\n"
-												"Either provide the file or change sslmode to disable server certificate verification.\n"));
+				appendPQExpBufferStr(&conn->errorMessage,
+									 libpq_gettext("could not get home directory to locate root certificate file\n"
+												   "Either provide the file or change sslmode to disable server certificate verification.\n"));
 			else
-				printfPQExpBuffer(&conn->errorMessage,
+				appendPQExpBuffer(&conn->errorMessage,
 								  libpq_gettext("root certificate file \"%s\" does not exist\n"
 												"Either provide the file or change sslmode to disable server certificate verification.\n"), fnbuf);
 			SSL_CTX_free(SSL_context);
@@ -939,7 +936,7 @@ initialize_SSL(PGconn *conn)
 		 */
 		if (errno != ENOENT && errno != ENOTDIR)
 		{
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("could not open certificate file \"%s\": %s\n"),
 							  fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
 			SSL_CTX_free(SSL_context);
@@ -958,7 +955,7 @@ initialize_SSL(PGconn *conn)
 		{
 			char	   *err = SSLerrmessage(ERR_get_error());
 
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("could not read certificate file \"%s\": %s\n"),
 							  fnbuf, err);
 			SSLerrfree(err);
@@ -983,7 +980,7 @@ initialize_SSL(PGconn *conn)
 	{
 		char	   *err = SSLerrmessage(ERR_get_error());
 
-		printfPQExpBuffer(&conn->errorMessage,
+		appendPQExpBuffer(&conn->errorMessage,
 						  libpq_gettext("could not establish SSL connection: %s\n"),
 						  err);
 		SSLerrfree(err);
@@ -1021,8 +1018,7 @@ initialize_SSL(PGconn *conn)
 
 			if (engine_str == NULL)
 			{
-				printfPQExpBuffer(&conn->errorMessage,
-								  libpq_gettext("out of memory\n"));
+				pqReportOOM(conn);
 				return -1;
 			}
 
@@ -1037,7 +1033,7 @@ initialize_SSL(PGconn *conn)
 			{
 				char	   *err = SSLerrmessage(ERR_get_error());
 
-				printfPQExpBuffer(&conn->errorMessage,
+				appendPQExpBuffer(&conn->errorMessage,
 								  libpq_gettext("could not load SSL engine \"%s\": %s\n"),
 								  engine_str, err);
 				SSLerrfree(err);
@@ -1049,7 +1045,7 @@ initialize_SSL(PGconn *conn)
 			{
 				char	   *err = SSLerrmessage(ERR_get_error());
 
-				printfPQExpBuffer(&conn->errorMessage,
+				appendPQExpBuffer(&conn->errorMessage,
 								  libpq_gettext("could not initialize SSL engine \"%s\": %s\n"),
 								  engine_str, err);
 				SSLerrfree(err);
@@ -1065,7 +1061,7 @@ initialize_SSL(PGconn *conn)
 			{
 				char	   *err = SSLerrmessage(ERR_get_error());
 
-				printfPQExpBuffer(&conn->errorMessage,
+				appendPQExpBuffer(&conn->errorMessage,
 								  libpq_gettext("could not read private SSL key \"%s\" from engine \"%s\": %s\n"),
 								  engine_colon, engine_str, err);
 				SSLerrfree(err);
@@ -1079,7 +1075,7 @@ initialize_SSL(PGconn *conn)
 			{
 				char	   *err = SSLerrmessage(ERR_get_error());
 
-				printfPQExpBuffer(&conn->errorMessage,
+				appendPQExpBuffer(&conn->errorMessage,
 								  libpq_gettext("could not load private SSL key \"%s\" from engine \"%s\": %s\n"),
 								  engine_colon, engine_str, err);
 				SSLerrfree(err);
@@ -1116,7 +1112,7 @@ initialize_SSL(PGconn *conn)
 
 		if (stat(fnbuf, &buf) != 0)
 		{
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("certificate present, but not private key file \"%s\"\n"),
 							  fnbuf);
 			return -1;
@@ -1124,7 +1120,7 @@ initialize_SSL(PGconn *conn)
 #ifndef WIN32
 		if (!S_ISREG(buf.st_mode) || buf.st_mode & (S_IRWXG | S_IRWXO))
 		{
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
 							  fnbuf);
 			return -1;
@@ -1135,7 +1131,7 @@ initialize_SSL(PGconn *conn)
 		{
 			char	   *err = SSLerrmessage(ERR_get_error());
 
-			printfPQExpBuffer(&conn->errorMessage,
+			appendPQExpBuffer(&conn->errorMessage,
 							  libpq_gettext("could not load private key file \"%s\": %s\n"),
 							  fnbuf, err);
 			SSLerrfree(err);
@@ -1149,7 +1145,7 @@ initialize_SSL(PGconn *conn)
 	{
 		char	   *err = SSLerrmessage(ERR_get_error());
 
-		printfPQExpBuffer(&conn->errorMessage,
+		appendPQExpBuffer(&conn->errorMessage,
 						  libpq_gettext("certificate does not match private key file \"%s\": %s\n"),
 						  fnbuf, err);
 		SSLerrfree(err);
@@ -1215,12 +1211,12 @@ open_client_SSL(PGconn *conn)
 					char		sebuf[256];
 
 					if (r == -1)
-						printfPQExpBuffer(&conn->errorMessage,
+						appendPQExpBuffer(&conn->errorMessage,
 										  libpq_gettext("SSL SYSCALL error: %s\n"),
 										  SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
 					else
-						printfPQExpBuffer(&conn->errorMessage,
-										  libpq_gettext("SSL SYSCALL error: EOF detected\n"));
+						appendPQExpBufferStr(&conn->errorMessage,
+											 libpq_gettext("SSL SYSCALL error: EOF detected\n"));
 					pgtls_close(conn);
 					return PGRES_POLLING_FAILED;
 				}
@@ -1228,7 +1224,7 @@ open_client_SSL(PGconn *conn)
 				{
 					char	   *err = SSLerrmessage(ecode);
 
-					printfPQExpBuffer(&conn->errorMessage,
+					appendPQExpBuffer(&conn->errorMessage,
 									  libpq_gettext("SSL error: %s\n"),
 									  err);
 					SSLerrfree(err);
@@ -1237,7 +1233,7 @@ open_client_SSL(PGconn *conn)
 				}
 
 			default:
-				printfPQExpBuffer(&conn->errorMessage,
+				appendPQExpBuffer(&conn->errorMessage,
 								  libpq_gettext("unrecognized SSL error code: %d\n"),
 								  err);
 				pgtls_close(conn);
@@ -1258,7 +1254,7 @@ open_client_SSL(PGconn *conn)
 
 		err = SSLerrmessage(ERR_get_error());
 
-		printfPQExpBuffer(&conn->errorMessage,
+		appendPQExpBuffer(&conn->errorMessage,
 						  libpq_gettext("certificate could not be obtained: %s\n"),
 						  err);
 		SSLerrfree(err);
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index f7dc249..157a738 100644
--- a/src/interfaces/libpq/fe-secure.c
+++ b/src/interfaces/libpq/fe-secure.c
@@ -205,8 +205,8 @@ pqsecure_close(PGconn *conn)
 /*
  *	Read data from a secure connection.
  *
- * On failure, this function is responsible for putting a suitable message
- * into conn->errorMessage.  The caller must still inspect errno, but only
+ * On failure, this function is responsible for appending a suitable message
+ * to conn->errorMessage.  The caller must still inspect errno, but only
  * to determine whether to continue/retry after error.
  */
 ssize_t
@@ -256,16 +256,15 @@ pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
 
 #ifdef ECONNRESET
 			case ECONNRESET:
-				printfPQExpBuffer(&conn->errorMessage,
-								  libpq_gettext(
-												"server closed the connection unexpectedly\n"
-												"\tThis probably means the server terminated abnormally\n"
-												"\tbefore or while processing the request.\n"));
+				appendPQExpBufferStr(&conn->errorMessage,
+									 libpq_gettext("server closed the connection unexpectedly\n"
+												   "\tThis probably means the server terminated abnormally\n"
+												   "\tbefore or while processing the request.\n"));
 				break;
 #endif
 
 			default:
-				printfPQExpBuffer(&conn->errorMessage,
+				appendPQExpBuffer(&conn->errorMessage,
 								  libpq_gettext("could not receive data from server: %s\n"),
 								  SOCK_STRERROR(result_errno,
 												sebuf, sizeof(sebuf)));
@@ -282,8 +281,8 @@ pqsecure_raw_read(PGconn *conn, void *ptr, size_t len)
 /*
  *	Write data to a secure connection.
  *
- * On failure, this function is responsible for putting a suitable message
- * into conn->errorMessage.  The caller must still inspect errno, but only
+ * On failure, this function is responsible for appending a suitable message
+ * to conn->errorMessage.  The caller must still inspect errno, but only
  * to determine whether to continue/retry after error.
  */
 ssize_t
@@ -366,15 +365,14 @@ retry_masked:
 
 			case ECONNRESET:
 #endif
-				printfPQExpBuffer(&conn->errorMessage,
-								  libpq_gettext(
-												"server closed the connection unexpectedly\n"
-												"\tThis probably means the server terminated abnormally\n"
-												"\tbefore or while processing the request.\n"));
+				appendPQExpBufferStr(&conn->errorMessage,
+									 libpq_gettext("server closed the connection unexpectedly\n"
+												   "\tThis probably means the server terminated abnormally\n"
+												   "\tbefore or while processing the request.\n"));
 				break;
 
 			default:
-				printfPQExpBuffer(&conn->errorMessage,
+				appendPQExpBuffer(&conn->errorMessage,
 								  libpq_gettext("could not send data to server: %s\n"),
 								  SOCK_STRERROR(result_errno,
 												sebuf, sizeof(sebuf)));
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index bc60373..22cfa4f 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -644,6 +644,8 @@ extern int pqWaitTimed(int forRead, int forWrite, PGconn *conn,
 			time_t finish_time);
 extern int	pqReadReady(PGconn *conn);
 extern int	pqWriteReady(PGconn *conn);
+extern void pqReportOOM(PGconn *conn);
+extern void pqReportOOMBuffer(PQExpBuffer errorMessage);
 
 /* === in fe-secure.c === */
 
@@ -679,7 +681,7 @@ extern void pgtls_init_library(bool do_ssl, int do_crypto);
  * The conn parameter is only used to be able to pass back an error
  * message - no connection-local setup is made here.
  *
- * Returns 0 if OK, -1 on failure (with a message in conn->errorMessage).
+ * Returns 0 if OK, -1 on failure (with a message added to conn->errorMessage).
  */
 extern int	pgtls_init(PGconn *conn);
 
@@ -696,8 +698,8 @@ extern void pgtls_close(PGconn *conn);
 /*
  *	Read data from a secure connection.
  *
- * On failure, this function is responsible for putting a suitable message
- * into conn->errorMessage.  The caller must still inspect errno, but only
+ * On failure, this function is responsible for appending a suitable message
+ * to conn->errorMessage.  The caller must still inspect errno, but only
  * to determine whether to continue/retry after error.
  */
 extern ssize_t pgtls_read(PGconn *conn, void *ptr, size_t len);
@@ -710,8 +712,8 @@ extern bool pgtls_read_pending(PGconn *conn);
 /*
  *	Write data to a secure connection.
  *
- * On failure, this function is responsible for putting a suitable message
- * into conn->errorMessage.  The caller must still inspect errno, but only
+ * On failure, this function is responsible for appending a suitable message
+ * to conn->errorMessage.  The caller must still inspect errno, but only
  * to determine whether to continue/retry after error.
  */
 extern ssize_t pgtls_write(PGconn *conn, const void *ptr, size_t len);
