diff -rpcd a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
*** a/src/backend/postmaster/postmaster.c	2014-01-05 05:17:12.000000000 +0900
--- b/src/backend/postmaster/postmaster.c	2014-01-20 14:22:05.000000000 +0900
***************
*** 100,105 ****
--- 100,106 ----
  #include "libpq/ip.h"
  #include "libpq/libpq.h"
  #include "libpq/pqsignal.h"
+ #include "mb/pg_wchar.h"
  #include "miscadmin.h"
  #include "pgstat.h"
  #include "postmaster/autovacuum.h"
*************** ProcessStartupPacket(Port *port, bool SS
*** 1742,1747 ****
--- 1743,1750 ----
  	void	   *buf;
  	ProtocolVersion proto;
  	MemoryContext oldcontext;
+ 	const char *client_encoding = NULL;
+ 	int			enc;
  
  	if (pq_getbytes((char *) &len, 4) == EOF)
  	{
*************** retry1:
*** 1912,1917 ****
--- 1915,1922 ----
  				port->guc_options = lappend(port->guc_options,
  											pstrdup(valptr));
  			}
+ 			if (strcmp(nameptr, "client_encoding") == 0)
+ 				client_encoding = valptr;
  			offset = valoffset + strlen(valptr) + 1;
  		}
  
*************** retry1:
*** 1946,1951 ****
--- 1951,1966 ----
  		port->guc_options = NIL;
  	}
  
+ 	/*
+ 	 * If the client encoding is the same as the server, localize and send
+ 	 * messages to the client in that encoding.
+ 	 */
+ 	if (client_encoding == NULL || client_encoding[0] == '\0')
+ 		client_encoding = GetConfigOption("client_encoding", true, false);
+ 	enc = pg_valid_client_encoding(client_encoding);
+ 	if (enc == pg_get_encoding_from_locale("", true))
+ 		enable_message_localization();
+ 
  	/* Check a user name was given. */
  	if (port->user_name == NULL || port->user_name[0] == '\0')
  		ereport(FATAL,
*************** BackendInitialize(Port *port)
*** 3970,3975 ****
--- 3985,3995 ----
  	enable_timeout_after(STARTUP_PACKET_TIMEOUT, AuthenticationTimeout * 1000);
  
  	/*
+ 	 * Output messages in English because client encoding is not known yet.
+ 	 */
+ 	disable_message_localization();
+ 
+ 	/*
  	 * Receive the startup packet (which might turn out to be a cancel request
  	 * packet).
  	 */
diff -rpcd a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
*** a/src/backend/utils/error/elog.c	2014-01-05 05:17:10.000000000 +0900
--- b/src/backend/utils/error/elog.c	2014-01-20 11:53:18.000000000 +0900
*************** static int	errordata_stack_depth = -1; /
*** 147,152 ****
--- 147,154 ----
  
  static int	recursion_depth = 0;	/* to detect actual recursion */
  
+ static bool localize_message = true;
+ 
  /* buffers for formatted timestamps that might be used by both
   * log_line_prefix and csv logs.
   */
*************** in_error_recursion_trouble(void)
*** 197,202 ****
--- 199,216 ----
  	return (recursion_depth > 2);
  }
  
+ void
+ enable_message_localization(void)
+ {
+ 	localize_message = true;
+ }
+ 
+ void
+ disable_message_localization(void)
+ {
+ 	localize_message = false;
+ }
+ 
  /*
   * One of those fallback steps is to stop trying to localize the error
   * message, since there's a significant probability that that's exactly
*************** static inline const char *
*** 206,212 ****
  err_gettext(const char *str)
  {
  #ifdef ENABLE_NLS
! 	if (in_error_recursion_trouble())
  		return str;
  	else
  		return gettext(str);
--- 220,226 ----
  err_gettext(const char *str)
  {
  #ifdef ENABLE_NLS
! 	if (!localize_message || in_error_recursion_trouble())
  		return str;
  	else
  		return gettext(str);
*************** errcode_for_socket_access(void)
*** 704,710 ****
  		char		   *fmtbuf; \
  		StringInfoData	buf; \
  		/* Internationalize the error format string */ \
! 		if (translateit && !in_error_recursion_trouble()) \
  			fmt = dgettext((domain), fmt);				  \
  		/* Expand %m in format string */ \
  		fmtbuf = expand_fmt_string(fmt, edata); \
--- 718,724 ----
  		char		   *fmtbuf; \
  		StringInfoData	buf; \
  		/* Internationalize the error format string */ \
! 		if (translateit && localize_message && !in_error_recursion_trouble()) \
  			fmt = dgettext((domain), fmt);				  \
  		/* Expand %m in format string */ \
  		fmtbuf = expand_fmt_string(fmt, edata); \
*************** errcode_for_socket_access(void)
*** 745,751 ****
  		char		   *fmtbuf; \
  		StringInfoData	buf; \
  		/* Internationalize the error format string */ \
! 		if (!in_error_recursion_trouble()) \
  			fmt = dngettext((domain), fmt_singular, fmt_plural, n); \
  		else \
  			fmt = (n == 1 ? fmt_singular : fmt_plural); \
--- 759,765 ----
  		char		   *fmtbuf; \
  		StringInfoData	buf; \
  		/* Internationalize the error format string */ \
! 		if (localize_message && !in_error_recursion_trouble()) \
  			fmt = dngettext((domain), fmt_singular, fmt_plural, n); \
  		else \
  			fmt = (n == 1 ? fmt_singular : fmt_plural); \
diff -rpcd a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
*** a/src/backend/utils/init/postinit.c	2014-01-05 05:17:10.000000000 +0900
--- b/src/backend/utils/init/postinit.c	2014-01-20 11:53:18.000000000 +0900
*************** InitPostgres(const char *in_dbname, Oid 
*** 736,741 ****
--- 736,744 ----
  		/* initialize client encoding */
  		InitializeClientEncoding();
  
+ 		/* now that client encoding is known, localize later messages */
+ 		enable_message_localization();
+ 
  		/* report this backend in the PgBackendStatus array */
  		pgstat_bestart();
  
*************** InitPostgres(const char *in_dbname, Oid 
*** 913,918 ****
--- 916,924 ----
  	/* initialize client encoding */
  	InitializeClientEncoding();
  
+ 	/* now that client encoding is known, localize later messages */
+ 	enable_message_localization();
+ 
  	/* report this backend in the PgBackendStatus array */
  	if (!bootstrap)
  		pgstat_bestart();
diff -rpcd a/src/include/utils/elog.h b/src/include/utils/elog.h
*** a/src/include/utils/elog.h	2014-01-05 05:17:05.000000000 +0900
--- b/src/include/utils/elog.h	2014-01-20 11:53:18.000000000 +0900
*************** extern char *Log_destination_string;
*** 440,445 ****
--- 440,447 ----
  extern void DebugFileOpen(void);
  extern char *unpack_sql_state(int sql_state);
  extern bool in_error_recursion_trouble(void);
+ extern void enable_message_localization(void);
+ extern void disable_message_localization(void);
  
  #ifdef HAVE_SYSLOG
  extern void set_syslog_parameters(const char *ident, int facility);
