diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index a0385eb0a1888de9a26e764a17c237c22fc2607e..9b9bb7dc8f046c5e0972a7b8a80d454c7ffea60c 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -814,14 +814,14 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
 	 * error.
 	 */
 	save_client_min_messages =
-		pstrdup(GetConfigOption("client_min_messages", false));
+		pstrdup(GetConfigOption("client_min_messages", false, false));
 	if (client_min_messages < WARNING)
 		(void) set_config_option("client_min_messages", "warning",
 								 PGC_USERSET, PGC_S_SESSION,
 								 GUC_ACTION_LOCAL, true);
 
 	save_log_min_messages =
-		pstrdup(GetConfigOption("log_min_messages", false));
+		pstrdup(GetConfigOption("log_min_messages", false, false));
 	if (log_min_messages < WARNING)
 		(void) set_config_option("log_min_messages", "warning",
 								 PGC_SUSET, PGC_S_SESSION,
@@ -836,7 +836,7 @@ execute_extension_script(Oid extensionOid, ExtensionControlFile *control,
 	 * but we cannot do that.  We have to actually set the search_path GUC in
 	 * case the extension script examines or changes it.
 	 */
-	save_search_path = pstrdup(GetConfigOption("search_path", false));
+	save_search_path = pstrdup(GetConfigOption("search_path", false, false));
 
 	initStringInfo(&pathbuf);
 	appendStringInfoString(&pathbuf, quote_identifier(schemaName));
diff --git a/src/backend/utils/misc/guc-file.l b/src/backend/utils/misc/guc-file.l
index 78907b939dee1383244042c9dbc48aed6ab76d35..3e9b10328d480b47dce5240d74577fdc7b715885 100644
--- a/src/backend/utils/misc/guc-file.l
+++ b/src/backend/utils/misc/guc-file.l
@@ -306,9 +306,9 @@ ProcessConfigFile(GucContext context)
 		/* In SIGHUP cases in the postmaster, report changes */
 		if (context == PGC_SIGHUP && !IsUnderPostmaster)
 		{
-			const char *preval = GetConfigOption(item->name, false);
+			const char *preval = GetConfigOption(item->name, true, false);
 
-			/* string variables could be NULL; treat that as empty */
+			/* If option doesn't exist yet or is NULL, treat as empty string */
 			if (!preval)
 				preval = "";
 			/* must dup, else might have dangling pointer below */
@@ -323,7 +323,7 @@ ProcessConfigFile(GucContext context)
 
 			if (pre_value)
 			{
-				const char *post_value = GetConfigOption(item->name, false);
+				const char *post_value = GetConfigOption(item->name, true, false);
 
 				if (!post_value)
 					post_value = "";
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 5a0e94f8014f4d1f91aefaed505aa21de796c934..5841631e8c3781fb6434c58f489ef610151d42c7 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -5828,8 +5828,11 @@ SetConfigOption(const char *name, const char *value,
 
 
 /*
- * Fetch the current value of the option `name'. If the option doesn't exist,
- * throw an ereport and don't return.
+ * Fetch the current value of the option `name', as a string.
+ *
+ * If the option doesn't exist, return NULL if missing_ok is true (NOTE that
+ * this cannot be distinguished from a string variable with a NULL value!),
+ * otherwise throw an ereport and don't return.
  *
  * If restrict_superuser is true, we also enforce that only superusers can
  * see GUC_SUPERUSER_ONLY variables.  This should only be passed as true
@@ -5839,16 +5842,21 @@ SetConfigOption(const char *name, const char *value,
  * valid until the next call to configuration related functions.
  */
 const char *
-GetConfigOption(const char *name, bool restrict_superuser)
+GetConfigOption(const char *name, bool missing_ok, bool restrict_superuser)
 {
 	struct config_generic *record;
 	static char buffer[256];
 
 	record = find_option(name, false, ERROR);
 	if (record == NULL)
+	{
+		if (missing_ok)
+			return NULL;
 		ereport(ERROR,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
-			   errmsg("unrecognized configuration parameter \"%s\"", name)));
+				 errmsg("unrecognized configuration parameter \"%s\"",
+						name)));
+	}
 	if (restrict_superuser &&
 		(record->flags & GUC_SUPERUSER_ONLY) &&
 		!superuser())
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index ee52cd735e33776ad647a57973cd261b7e4b1b62..011f6b7f001a60ce1fcfb732264238f5d355866d 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -296,7 +296,8 @@ extern void DefineCustomEnumVariable(
 
 extern void EmitWarningsOnPlaceholders(const char *className);
 
-extern const char *GetConfigOption(const char *name, bool restrict_superuser);
+extern const char *GetConfigOption(const char *name, bool missing_ok,
+				bool restrict_superuser);
 extern const char *GetConfigOptionResetString(const char *name);
 extern void ProcessConfigFile(GucContext context);
 extern void InitializeGUCOptions(void);