diff --git a/src/backend/utils/error/elog.c b/src/backend/utils/error/elog.c
index b9c11301ca..9bf86b57a0 100644
--- a/src/backend/utils/error/elog.c
+++ b/src/backend/utils/error/elog.c
@@ -177,7 +177,6 @@ static void write_csvlog(ErrorData *edata);
 static void send_message_to_server_log(ErrorData *edata);
 static void write_pipe_chunks(char *data, int len, int dest);
 static void send_message_to_frontend(ErrorData *edata);
-static const char *error_severity(int elevel);
 static void append_with_tabs(StringInfo buf, const char *str);
 static bool is_log_level_output(int elevel, int log_min_level);
 
@@ -3325,7 +3324,7 @@ send_message_to_frontend(ErrorData *edata)
  * The string is not localized here, but we mark the strings for translation
  * so that callers can invoke _() on the result.
  */
-static const char *
+const char *
 error_severity(int elevel)
 {
 	const char *prefix;
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index e471d7f53c..004a0497e7 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -166,6 +166,7 @@ static int	syslog_facility = 0;
 static void assign_syslog_facility(int newval, void *extra);
 static void assign_syslog_ident(const char *newval, void *extra);
 static void assign_session_replication_role(int newval, void *extra);
+static bool check_client_min_messages (int *newval, void **extra, GucSource source);
 static bool check_temp_buffers(int *newval, void **extra, GucSource source);
 static bool check_bonjour(bool *newval, void **extra, GucSource source);
 static bool check_ssl(bool *newval, void **extra, GucSource source);
@@ -3931,7 +3932,7 @@ static struct config_enum ConfigureNamesEnum[] =
 		},
 		&client_min_messages,
 		NOTICE, client_message_level_options,
-		NULL, NULL, NULL
+		check_client_min_messages, NULL, NULL
 	},
 
 	{
@@ -10259,6 +10260,22 @@ call_enum_check_hook(struct config_enum *conf, int *newval, void **extra,
 	return true;
 }
 
+static bool
+check_client_min_messages (int *newval, void **extra, GucSource source)
+{
+	int newLogLevel = *newval;
+
+	if (newLogLevel == FATAL || newLogLevel == PANIC)
+	{
+		elog(WARNING,
+			"frontend protocol requires %s or below (coerced to %s from %s)",
+			error_severity(ERROR), error_severity(ERROR),
+			error_severity(newLogLevel));
+		*newval = ERROR;
+	}
+
+	return true;
+}
 
 /*
  * check_hook, assign_hook and show_hook subroutines
diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h
index 33c6b53e27..2e3f9e2163 100644
--- a/src/include/utils/elog.h
+++ b/src/include/utils/elog.h
@@ -416,6 +416,7 @@ extern bool syslog_split_messages;
 extern void DebugFileOpen(void);
 extern char *unpack_sql_state(int sql_state);
 extern bool in_error_recursion_trouble(void);
+extern const char *error_severity(int elevel);
 
 #ifdef HAVE_SYSLOG
 extern void set_syslog_parameters(const char *ident, int facility);
