diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index 5d0fbdfb40fa79a01304ef72a632c2c47f0bab7d..9efd20f2bcfd29e3006df8582d0a214087dec601 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -759,12 +759,16 @@ bool
 check_client_encoding(char **newval, void **extra, GucSource source)
 {
 	int			encoding;
+	const char *canonical_name;
 
 	/* Look up the encoding by name */
 	encoding = pg_valid_client_encoding(*newval);
 	if (encoding < 0)
 		return false;
 
+	/* Get the canonical name (no aliases, uniform case) */
+	canonical_name = pg_encoding_to_char(encoding);
+
 	/*
 	 * If we are not within a transaction then PrepareClientEncoding will not
 	 * be able to look up the necessary conversion procs.  If we are still
@@ -786,7 +790,7 @@ check_client_encoding(char **newval, void **extra, GucSource source)
 			/* Must be a genuine no-such-conversion problem */
 			GUC_check_errcode(ERRCODE_FEATURE_NOT_SUPPORTED);
 			GUC_check_errdetail("Conversion between %s and %s is not supported.",
-								pg_encoding_to_char(encoding),
+								canonical_name,
 								GetDatabaseEncodingName());
 		}
 		else
@@ -798,13 +802,27 @@ check_client_encoding(char **newval, void **extra, GucSource source)
 	}
 
 	/*
-	 * Return the encoding's canonical name, and save its ID in *extra.
+	 * Replace the user-supplied string with the encoding's canonical name.
+	 * This gets rid of aliases and case-folding variations.
+	 *
+	 * XXX Although canonicalizing seems like a good idea in the abstract, it
+	 * breaks pre-9.1 JDBC drivers, which expect that if they send "UNICODE"
+	 * as the client_encoding setting then it will read back the same way.
+	 * As a workaround, don't replace the string if it's "UNICODE".  Remove
+	 * that hack when pre-9.1 JDBC drivers are no longer in use.
 	 */
-	free(*newval);
-	*newval = strdup(pg_encoding_to_char(encoding));
-	if (!*newval)
-		return false;
+	if (strcmp(*newval, canonical_name) != 0 &&
+		strcmp(*newval, "UNICODE") != 0)
+	{
+		free(*newval);
+		*newval = strdup(canonical_name);
+		if (!*newval)
+			return false;
+	}
 
+	/*
+	 * Save the encoding's ID in *extra, for use by assign_client_encoding.
+	 */
 	*extra = malloc(sizeof(int));
 	if (!*extra)
 		return false;