diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index fdf8b3e9c7..23c77ab050 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -959,9 +959,8 @@ include_dir 'conf.d'
        <para>
         Enables <acronym>SSL</> connections. Please read
         <xref linkend="ssl-tcp"> before using this. The default
-        is <literal>off</>. This parameter can only be set at server
-        start.  <acronym>SSL</> communication is only possible with
-        TCP/IP connections.
+        is <literal>off</>. <acronym>SSL</> communication is only
+        possible with TCP/IP connections.
        </para>
       </listitem>
      </varlistentry>
@@ -979,7 +978,7 @@ include_dir 'conf.d'
         and client certificate verification is not performed.  (In previous
         releases of PostgreSQL, the name of this file was hard-coded
         as <filename>root.crt</filename>.)  Relative paths are relative to the
-        data directory.  This parameter can only be set at server start.
+        data directory.
        </para>
       </listitem>
      </varlistentry>
@@ -994,8 +993,7 @@ include_dir 'conf.d'
        <para>
         Specifies the name of the file containing the SSL server certificate.
         The default is <filename>server.crt</filename>.  Relative paths are
-        relative to the data directory.  This parameter can only be set at
-        server start.
+        relative to the data directory.
        </para>
       </listitem>
      </varlistentry>
@@ -1012,8 +1010,7 @@ include_dir 'conf.d'
         revocation list (CRL).  The default is empty, meaning no CRL file is
         loaded.  (In previous releases of PostgreSQL, the name of this file was
         hard-coded as <filename>root.crl</filename>.)  Relative paths are
-        relative to the data directory.  This parameter can only be set at
-        server start.
+        relative to the data directory.
        </para>
       </listitem>
      </varlistentry>
@@ -1028,8 +1025,7 @@ include_dir 'conf.d'
        <para>
         Specifies the name of the file containing the SSL server private key.
         The default is <filename>server.key</filename>.  Relative paths are
-        relative to the data directory.  This parameter can only be set at
-        server start.
+        relative to the data directory.
        </para>
       </listitem>
      </varlistentry>
diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index 787cfce987..5e78d81607 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -2288,8 +2288,8 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
     The files <filename>server.key</>, <filename>server.crt</>,
     <filename>root.crt</filename>, and <filename>root.crl</filename>
     (or their configured alternative names)
-    are only examined during server start; so you must restart
-    the server for changes in them to take effect.
+    are examined when reloading the configuration, or when spawning the backend
+    process on <systemitem class="osname">Windows</> systems.
    </para>
   </sect2>
 
diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c
index 668f217bba..e1d33a9e48 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -77,12 +77,13 @@ static DH  *generate_dh_parameters(int prime_len, int generator);
 static DH  *tmp_dh_cb(SSL *s, int is_export, int keylength);
 static int	verify_cb(int, X509_STORE_CTX *);
 static void info_cb(const SSL *ssl, int type, int args);
-static void initialize_ecdh(void);
+static bool initialize_ecdh(SSL_CTX *context, bool failOnError);
 static const char *SSLerrmessage(unsigned long ecode);
 
 static char *X509_NAME_to_cstring(X509_NAME *name);
 
 static SSL_CTX *SSL_context = NULL;
+static bool SSL_initialized = false;
 
 /* ------------------------------------------------------------ */
 /*						 Hardcoded values						*/
@@ -157,14 +158,15 @@ KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI=\n\
 /*
  *	Initialize global SSL context.
  */
-void
-be_tls_init(void)
+int
+be_tls_init(bool failOnError)
 {
 	struct stat buf;
 
-	STACK_OF(X509_NAME) *root_cert_list = NULL;
+	STACK_OF(X509_NAME)	   *root_cert_list = NULL;
+	SSL_CTX				   *context;
 
-	if (!SSL_context)
+	if (!SSL_initialized)
 	{
 #ifdef HAVE_OPENSSL_INIT_SSL
 		OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL);
@@ -173,121 +175,153 @@ be_tls_init(void)
 		SSL_library_init();
 		SSL_load_error_strings();
 #endif
+		SSL_initialized = true;
+	}
 
-		/*
-		 * We use SSLv23_method() because it can negotiate use of the highest
-		 * mutually supported protocol version, while alternatives like
-		 * TLSv1_2_method() permit only one specific version.  Note that we
-		 * don't actually allow SSL v2 or v3, only TLS protocols (see below).
-		 */
-		SSL_context = SSL_CTX_new(SSLv23_method());
-		if (!SSL_context)
-			ereport(FATAL,
-					(errmsg("could not create SSL context: %s",
-							SSLerrmessage(ERR_get_error()))));
+	/*
+	 * We use SSLv23_method() because it can negotiate use of the highest
+	 * mutually supported protocol version, while alternatives like
+	 * TLSv1_2_method() permit only one specific version.  Note that we don't
+	 * actually allow SSL v2 or v3, only TLS protocols (see below).
+	 */
+	context = SSL_CTX_new(SSLv23_method());
+	if (!context)
+	{
+		ereport(failOnError ? FATAL : WARNING,
+				(errmsg("could not create SSL context: %s",
+						SSLerrmessage(ERR_get_error()))));
+		goto error;
+	}
 
-		/*
-		 * Disable OpenSSL's moving-write-buffer sanity check, because it
-		 * causes unnecessary failures in nonblocking send cases.
-		 */
-		SSL_CTX_set_mode(SSL_context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
+	/*
+	 * Disable OpenSSL's moving-write-buffer sanity check, because it causes
+	 * unnecessary failures in nonblocking send cases.
+	 */
+	SSL_CTX_set_mode(context, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
 
-		/*
-		 * Load and verify server's certificate and private key
-		 */
-		if (SSL_CTX_use_certificate_chain_file(SSL_context,
-											   ssl_cert_file) != 1)
-			ereport(FATAL,
-					(errcode(ERRCODE_CONFIG_FILE_ERROR),
-				  errmsg("could not load server certificate file \"%s\": %s",
-						 ssl_cert_file, SSLerrmessage(ERR_get_error()))));
-
-		if (stat(ssl_key_file, &buf) != 0)
-			ereport(FATAL,
-					(errcode_for_file_access(),
-					 errmsg("could not access private key file \"%s\": %m",
-							ssl_key_file)));
-
-		if (!S_ISREG(buf.st_mode))
-			ereport(FATAL,
-					(errcode(ERRCODE_CONFIG_FILE_ERROR),
-					 errmsg("private key file \"%s\" is not a regular file",
-							ssl_key_file)));
+	/*
+	 * Load and verify server's certificate and private key
+	 */
+	if (SSL_CTX_use_certificate_chain_file(context, ssl_cert_file) != 1)
+	{
+		ereport(failOnError ? FATAL : WARNING,
+				(errcode(ERRCODE_CONFIG_FILE_ERROR),
+				 errmsg("could not load server certificate file \"%s\": %s",
+						ssl_cert_file, SSLerrmessage(ERR_get_error()))));
+		goto error;
+	}
 
-		/*
-		 * Refuse to load files owned by users other than us or root.
-		 *
-		 * XXX surely we can check this on Windows somehow, too.
-		 */
+	if (stat(ssl_key_file, &buf) != 0)
+	{
+		ereport(failOnError ? FATAL : WARNING,
+				(errcode_for_file_access(),
+				 errmsg("could not access private key file \"%s\": %m",
+						ssl_key_file)));
+		goto error;
+	}
+
+	if (!S_ISREG(buf.st_mode))
+	{
+		ereport(failOnError ? FATAL : WARNING,
+				(errcode(ERRCODE_CONFIG_FILE_ERROR),
+				 errmsg("private key file \"%s\" is not a regular file",
+						ssl_key_file)));
+		goto error;
+	}
+
+	/*
+	 * Refuse to load files owned by users other than us or root.
+	 *
+	 * XXX surely we can check this on Windows somehow, too.
+	 */
 #if !defined(WIN32) && !defined(__CYGWIN__)
-		if (buf.st_uid != geteuid() && buf.st_uid != 0)
-			ereport(FATAL,
-					(errcode(ERRCODE_CONFIG_FILE_ERROR),
-					 errmsg("private key file \"%s\" must be owned by the database user or root",
-							ssl_key_file)));
+	if (buf.st_uid != geteuid() && buf.st_uid != 0)
+	{
+		ereport(failOnError ? FATAL : WARNING,
+				(errcode(ERRCODE_CONFIG_FILE_ERROR),
+				 errmsg("private key file \"%s\" must be owned by the database user or root",
+						ssl_key_file)));
+		goto error;
+	}
 #endif
 
-		/*
-		 * Require no public access to key file. If the file is owned by us,
-		 * require mode 0600 or less. If owned by root, require 0640 or less
-		 * to allow read access through our gid, or a supplementary gid that
-		 * allows to read system-wide certificates.
-		 *
-		 * XXX temporarily suppress check when on Windows, because there may
-		 * not be proper support for Unix-y file permissions.  Need to think
-		 * of a reasonable check to apply on Windows.  (See also the data
-		 * directory permission check in postmaster.c)
-		 */
+	/*
+	 * Require no public access to key file. If the file is owned by us,
+	 * require mode 0600 or less. If owned by root, require 0640 or less
+	 * to allow read access through our gid, or a supplementary gid that
+	 * allows to read system-wide certificates.
+	 *
+	 * XXX temporarily suppress check when on Windows, because there may
+	 * not be proper support for Unix-y file permissions.  Need to think
+	 * of a reasonable check to apply on Windows.  (See also the data
+	 * directory permission check in postmaster.c)
+	 */
 #if !defined(WIN32) && !defined(__CYGWIN__)
-		if ((buf.st_uid == geteuid() && buf.st_mode & (S_IRWXG | S_IRWXO)) ||
-			(buf.st_uid == 0 && buf.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)))
-			ereport(FATAL,
-					(errcode(ERRCODE_CONFIG_FILE_ERROR),
-				  errmsg("private key file \"%s\" has group or world access",
-						 ssl_key_file),
-					 errdetail("File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root.")));
+	if ((buf.st_uid == geteuid() && buf.st_mode & (S_IRWXG | S_IRWXO)) ||
+		(buf.st_uid == 0 && buf.st_mode & (S_IWGRP | S_IXGRP | S_IRWXO)))
+	{
+		ereport(failOnError ? FATAL : WARNING,
+				(errcode(ERRCODE_CONFIG_FILE_ERROR),
+				 errmsg("private key file \"%s\" has group or world access",
+						ssl_key_file),
+				 errdetail("File must have permissions u=rw (0600) or less if owned by the database user, or permissions u=rw,g=r (0640) or less if owned by root.")));
+		goto error;
+	}
 #endif
 
-		if (SSL_CTX_use_PrivateKey_file(SSL_context,
-										ssl_key_file,
-										SSL_FILETYPE_PEM) != 1)
-			ereport(FATAL,
-					(errmsg("could not load private key file \"%s\": %s",
-							ssl_key_file, SSLerrmessage(ERR_get_error()))));
-
-		if (SSL_CTX_check_private_key(SSL_context) != 1)
-			ereport(FATAL,
-					(errmsg("check of private key failed: %s",
-							SSLerrmessage(ERR_get_error()))));
+	if (SSL_CTX_use_PrivateKey_file(context,
+									ssl_key_file,
+									SSL_FILETYPE_PEM) != 1)
+	{
+		ereport(failOnError ? FATAL : WARNING,
+				(errmsg("could not load private key file \"%s\": %s",
+						ssl_key_file, SSLerrmessage(ERR_get_error()))));
+		goto error;
+	}
+
+	if (SSL_CTX_check_private_key(context) != 1)
+	{
+		ereport(failOnError ? FATAL : WARNING,
+				(errmsg("check of private key failed: %s",
+						SSLerrmessage(ERR_get_error()))));
+		goto error;
 	}
 
 	/* set up ephemeral DH keys, and disallow SSL v2/v3 while at it */
-	SSL_CTX_set_tmp_dh_callback(SSL_context, tmp_dh_cb);
-	SSL_CTX_set_options(SSL_context,
+	SSL_CTX_set_tmp_dh_callback(context, tmp_dh_cb);
+	SSL_CTX_set_options(context,
 						SSL_OP_SINGLE_DH_USE |
 						SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
 
 	/* set up ephemeral ECDH keys */
-	initialize_ecdh();
+	if (!initialize_ecdh(context, failOnError))
+		goto error;
 
 	/* set up the allowed cipher list */
-	if (SSL_CTX_set_cipher_list(SSL_context, SSLCipherSuites) != 1)
-		elog(FATAL, "could not set the cipher list (no valid ciphers available)");
+	if (SSL_CTX_set_cipher_list(context, SSLCipherSuites) != 1)
+	{
+		ereport(failOnError ? FATAL : WARNING,
+				(errmsg("could not set the cipher list (no valid ciphers available)")));
+		goto error;
+	}
 
 	/* Let server choose order */
 	if (SSLPreferServerCiphers)
-		SSL_CTX_set_options(SSL_context, SSL_OP_CIPHER_SERVER_PREFERENCE);
+		SSL_CTX_set_options(context, SSL_OP_CIPHER_SERVER_PREFERENCE);
 
 	/*
 	 * Load CA store, so we can verify client certificates if needed.
 	 */
 	if (ssl_ca_file[0])
 	{
-		if (SSL_CTX_load_verify_locations(SSL_context, ssl_ca_file, NULL) != 1 ||
+		if (SSL_CTX_load_verify_locations(context, ssl_ca_file, NULL) != 1 ||
 			(root_cert_list = SSL_load_client_CA_file(ssl_ca_file)) == NULL)
-			ereport(FATAL,
+		{
+			ereport(failOnError ? FATAL : WARNING,
 					(errmsg("could not load root certificate file \"%s\": %s",
 							ssl_ca_file, SSLerrmessage(ERR_get_error()))));
+			goto error;
+		}
 	}
 
 	/*----------
@@ -297,7 +331,7 @@ be_tls_init(void)
 	 */
 	if (ssl_crl_file[0])
 	{
-		X509_STORE *cvstore = SSL_CTX_get_cert_store(SSL_context);
+		X509_STORE *cvstore = SSL_CTX_get_cert_store(context);
 
 		if (cvstore)
 		{
@@ -316,9 +350,12 @@ be_tls_init(void)
 #endif
 			}
 			else
-				ereport(FATAL,
+			{
+				ereport(failOnError ? FATAL : WARNING,
 						(errmsg("could not load SSL certificate revocation list file \"%s\": %s",
 							 ssl_crl_file, SSLerrmessage(ERR_get_error()))));
+				goto error;
+			}
 		}
 	}
 
@@ -329,7 +366,7 @@ be_tls_init(void)
 		 * presented.  We might fail such connections later, depending on what
 		 * we find in pg_hba.conf.
 		 */
-		SSL_CTX_set_verify(SSL_context,
+		SSL_CTX_set_verify(context,
 						   (SSL_VERIFY_PEER |
 							SSL_VERIFY_CLIENT_ONCE),
 						   verify_cb);
@@ -342,8 +379,34 @@ be_tls_init(void)
 		 * CertificateRequests.  This lets a client with a keystore select the
 		 * appropriate client certificate to send to us.
 		 */
-		SSL_CTX_set_client_CA_list(SSL_context, root_cert_list);
+		SSL_CTX_set_client_CA_list(context, root_cert_list);
 	}
+	else
+		ssl_loaded_verify_locations = false;
+
+
+	SSL_CTX_free(SSL_context);
+	SSL_context = context;
+
+	return 0;
+
+error:
+	SSL_CTX_free(context); \
+
+	return -1;
+}
+
+/*
+ *	Destroy global SSL context.
+ */
+void
+be_tls_destroy(void)
+{
+	if (SSL_context == NULL)
+		return;
+
+	SSL_CTX_free(SSL_context);
+	SSL_context = NULL;
 }
 
 /*
@@ -1034,8 +1097,8 @@ info_cb(const SSL *ssl, int type, int args)
 	}
 }
 
-static void
-initialize_ecdh(void)
+static bool
+initialize_ecdh(SSL_CTX *context, bool failOnError)
 {
 #ifndef OPENSSL_NO_ECDH
 	EC_KEY	   *ecdh;
@@ -1043,18 +1106,26 @@ initialize_ecdh(void)
 
 	nid = OBJ_sn2nid(SSLECDHCurve);
 	if (!nid)
-		ereport(FATAL,
+	{
+		ereport(failOnError ? FATAL : WARNING,
 				(errmsg("ECDH: unrecognized curve name: %s", SSLECDHCurve)));
+		return false;
+	}
 
 	ecdh = EC_KEY_new_by_curve_name(nid);
 	if (!ecdh)
-		ereport(FATAL,
+	{
+		ereport(failOnError ? FATAL : WARNING,
 				(errmsg("ECDH: could not create key")));
+		return false;
+	}
 
-	SSL_CTX_set_options(SSL_context, SSL_OP_SINGLE_ECDH_USE);
-	SSL_CTX_set_tmp_ecdh(SSL_context, ecdh);
+	SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE);
+	SSL_CTX_set_tmp_ecdh(context, ecdh);
 	EC_KEY_free(ecdh);
 #endif
+
+	return true;
 }
 
 /*
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c
index b267507de9..bd45da4a3e 100644
--- a/src/backend/libpq/be-secure.c
+++ b/src/backend/libpq/be-secure.c
@@ -64,15 +64,28 @@ bool		SSLPreferServerCiphers;
 
 /*
  *	Initialize global context
+ *
+ *	Returns 0 if OK, -1 on failure.
  */
 int
-secure_initialize(void)
+secure_initialize(bool failOnError)
 {
 #ifdef USE_SSL
-	be_tls_init();
+	return be_tls_init(failOnError);
+#else
+	return 0;
 #endif
+}
 
-	return 0;
+/*
+ *	Destroy global context
+ */
+void
+secure_destroy(void)
+{
+#ifdef USE_SSL
+	be_tls_destroy();
+#endif
 }
 
 /*
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 24add74512..943796ac7f 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -241,6 +241,9 @@ bool		enable_bonjour = false;
 char	   *bonjour_name;
 bool		restart_after_crash = true;
 
+/* Set when and if SSL has been initialized properly */
+static bool LoadedSSL = false;
+
 /* PIDs of special child processes; 0 when not running */
 static pid_t StartupPID = 0,
 			BgWriterPID = 0,
@@ -929,7 +932,10 @@ PostmasterMain(int argc, char *argv[])
 	 */
 #ifdef USE_SSL
 	if (EnableSSL)
-		secure_initialize();
+	{
+		(void) secure_initialize(true);
+		LoadedSSL = true;
+	}
 #endif
 
 	/*
@@ -1958,7 +1964,7 @@ ProcessStartupPacket(Port *port, bool SSLdone)
 
 #ifdef USE_SSL
 		/* No SSL when disabled or on Unix sockets */
-		if (!EnableSSL || IS_AF_UNIX(port->laddr.addr.ss_family))
+		if (!LoadedSSL || IS_AF_UNIX(port->laddr.addr.ss_family))
 			SSLok = 'N';
 		else
 			SSLok = 'S';		/* Support for SSL */
@@ -2511,6 +2517,22 @@ SIGHUP_handler(SIGNAL_ARGS)
 			ereport(WARNING,
 					(errmsg("pg_ident.conf not reloaded")));
 
+#ifdef USE_SSL
+		if (EnableSSL)
+		{
+			if (secure_initialize(false) != 0)
+				ereport(WARNING,
+						(errmsg("SSL context not reloaded")));
+			else
+				LoadedSSL = true;
+		}
+		else
+		{
+			secure_destroy();
+			LoadedSSL = false;
+		}
+#endif
+
 #ifdef EXEC_BACKEND
 		/* Update the starting-point file for future children */
 		write_nondefault_variables(PGC_SIGHUP);
@@ -4734,7 +4756,10 @@ SubPostmasterMain(int argc, char *argv[])
 		 */
 #ifdef USE_SSL
 		if (EnableSSL)
-			secure_initialize();
+		{
+			(void) secure_initialize(true);
+			LoadedSSL = true;
+		}
 #endif
 
 		/*
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 4e49d5b79c..2478f0afac 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -935,7 +935,7 @@ static struct config_bool ConfigureNamesBool[] =
 		NULL, NULL, NULL
 	},
 	{
-		{"ssl", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+		{"ssl", PGC_SIGHUP, CONN_AUTH_SECURITY,
 			gettext_noop("Enables SSL connections."),
 			NULL
 		},
@@ -944,7 +944,7 @@ static struct config_bool ConfigureNamesBool[] =
 		check_ssl, NULL, NULL
 	},
 	{
-		{"ssl_prefer_server_ciphers", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+		{"ssl_prefer_server_ciphers", PGC_SIGHUP, CONN_AUTH_SECURITY,
 			gettext_noop("Give priority to server ciphersuite order."),
 			NULL
 		},
@@ -3445,7 +3445,7 @@ static struct config_string ConfigureNamesString[] =
 	},
 
 	{
-		{"ssl_cert_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+		{"ssl_cert_file", PGC_SIGHUP, CONN_AUTH_SECURITY,
 			gettext_noop("Location of the SSL server certificate file."),
 			NULL
 		},
@@ -3455,7 +3455,7 @@ static struct config_string ConfigureNamesString[] =
 	},
 
 	{
-		{"ssl_key_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+		{"ssl_key_file", PGC_SIGHUP, CONN_AUTH_SECURITY,
 			gettext_noop("Location of the SSL server private key file."),
 			NULL
 		},
@@ -3465,7 +3465,7 @@ static struct config_string ConfigureNamesString[] =
 	},
 
 	{
-		{"ssl_ca_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+		{"ssl_ca_file", PGC_SIGHUP, CONN_AUTH_SECURITY,
 			gettext_noop("Location of the SSL certificate authority file."),
 			NULL
 		},
@@ -3475,7 +3475,7 @@ static struct config_string ConfigureNamesString[] =
 	},
 
 	{
-		{"ssl_crl_file", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+		{"ssl_crl_file", PGC_SIGHUP, CONN_AUTH_SECURITY,
 			gettext_noop("Location of the SSL certificate revocation list file."),
 			NULL
 		},
@@ -3517,7 +3517,7 @@ static struct config_string ConfigureNamesString[] =
 	},
 
 	{
-		{"ssl_ciphers", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+		{"ssl_ciphers", PGC_SIGHUP, CONN_AUTH_SECURITY,
 			gettext_noop("Sets the list of allowed SSL ciphers."),
 			NULL,
 			GUC_SUPERUSER_ONLY
@@ -3532,7 +3532,7 @@ static struct config_string ConfigureNamesString[] =
 	},
 
 	{
-		{"ssl_ecdh_curve", PGC_POSTMASTER, CONN_AUTH_SECURITY,
+		{"ssl_ecdh_curve", PGC_SIGHUP, CONN_AUTH_SECURITY,
 			gettext_noop("Sets the curve to use for ECDH."),
 			NULL,
 			GUC_SUPERUSER_ONLY
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 1f490c7de4..3199b9386a 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -76,15 +76,14 @@
 # - Security and Authentication -
 
 #authentication_timeout = 1min		# 1s-600s
-#ssl = off				# (change requires restart)
+#ssl = off
 #ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers
-					# (change requires restart)
-#ssl_prefer_server_ciphers = on		# (change requires restart)
-#ssl_ecdh_curve = 'prime256v1'		# (change requires restart)
-#ssl_cert_file = 'server.crt'		# (change requires restart)
-#ssl_key_file = 'server.key'		# (change requires restart)
-#ssl_ca_file = ''			# (change requires restart)
-#ssl_crl_file = ''			# (change requires restart)
+#ssl_prefer_server_ciphers = on
+#ssl_ecdh_curve = 'prime256v1'
+#ssl_cert_file = 'server.crt'
+#ssl_key_file = 'server.key'
+#ssl_ca_file = ''
+#ssl_crl_file = ''
 #password_encryption = md5		# md5 or plain
 #db_user_namespace = off
 #row_security = on
diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h
index b91eca5b2c..26cd60b39f 100644
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -200,7 +200,8 @@ typedef struct Port
  * These functions are implemented by the glue code specific to each
  * SSL implementation (e.g. be-secure-openssl.c)
  */
-extern void be_tls_init(void);
+extern int	be_tls_init(bool failOnError);
+extern void be_tls_destroy(void);
 extern int	be_tls_open_server(Port *port);
 extern void be_tls_close(Port *port);
 extern ssize_t be_tls_read(Port *port, void *ptr, size_t len, int *waitfor);
diff --git a/src/include/libpq/libpq.h b/src/include/libpq/libpq.h
index 5fac8171ed..66ceb2b4a0 100644
--- a/src/include/libpq/libpq.h
+++ b/src/include/libpq/libpq.h
@@ -81,7 +81,7 @@ extern char *ssl_key_file;
 extern char *ssl_ca_file;
 extern char *ssl_crl_file;
 
-extern int	secure_initialize(void);
+extern int	secure_initialize(bool failOnError);
 extern bool secure_loaded_verify_locations(void);
 extern void secure_destroy(void);
 extern int	secure_open_server(Port *port);
diff --git a/src/test/ssl/ServerSetup.pm b/src/test/ssl/ServerSetup.pm
index d312880f8b..20eaf76bff 100644
--- a/src/test/ssl/ServerSetup.pm
+++ b/src/test/ssl/ServerSetup.pm
@@ -70,7 +70,11 @@ sub configure_test_server_for_ssl
 
 	close CONF;
 
-# Copy all server certificates and keys, and client root cert, to the data dir
+	# ssl configuration will be placed here
+	open SSLCONF, ">$pgdata/sslconfig.conf";
+	close SSLCONF;
+
+	# Copy all server certificates and keys, and client root cert, to the data dir
 	copy_files("ssl/server-*.crt", $pgdata);
 	copy_files("ssl/server-*.key", $pgdata);
 	chmod(0600, glob "$pgdata/server-*.key") or die $!;
@@ -78,25 +82,14 @@ sub configure_test_server_for_ssl
 	copy_files("ssl/root_ca.crt", $pgdata);
 	copy_files("ssl/root+client.crl",    $pgdata);
 
-  # Only accept SSL connections from localhost. Our tests don't depend on this
-  # but seems best to keep it as narrow as possible for security reasons.
-  #
-  # When connecting to certdb, also check the client certificate.
-	open HBA, ">$pgdata/pg_hba.conf";
-	print HBA
-"# TYPE  DATABASE        USER            ADDRESS                 METHOD\n";
-	print HBA
-"hostssl trustdb         ssltestuser     $serverhost/32            trust\n";
-	print HBA
-"hostssl trustdb         ssltestuser     ::1/128                 trust\n";
-	print HBA
-"hostssl certdb          ssltestuser     $serverhost/32            cert\n";
-	print HBA
-"hostssl certdb          ssltestuser     ::1/128                 cert\n";
-	close HBA;
+	# Stop and restart server to load new listen_addresses.
+	$node->restart;
+
+	# Change pg_hba after restart because hostssl requires ssl=on
+	configure_hba_for_ssl($node, $serverhost);
 }
 
-# Change the configuration to use given server cert file, and restart
+# Change the configuration to use given server cert file, and reload
 # the server so that the configuration takes effect.
 sub switch_server_cert
 {
@@ -105,7 +98,7 @@ sub switch_server_cert
 	my $cafile = $_[2] || "root+client_ca";
 	my $pgdata   = $node->data_dir;
 
-	diag "Restarting server with certfile \"$certfile\" and cafile \"$cafile\"...";
+	diag "Reloading server with certfile \"$certfile\" and cafile \"$cafile\"...";
 
 	open SSLCONF, ">$pgdata/sslconfig.conf";
 	print SSLCONF "ssl=on\n";
@@ -115,6 +108,29 @@ sub switch_server_cert
 	print SSLCONF "ssl_crl_file='root+client.crl'\n";
 	close SSLCONF;
 
-	# Stop and restart server to reload the new config.
-	$node->restart;
+	$node->reload;
+}
+
+sub configure_hba_for_ssl
+{
+	my $node       = $_[0];
+	my $serverhost = $_[1];
+	my $pgdata     = $node->data_dir;
+
+	# Only accept SSL connections from localhost. Our tests don't depend on this
+	# but seems best to keep it as narrow as possible for security reasons.
+	#
+	# When connecting to certdb, also check the client certificate.
+	open HBA, ">$pgdata/pg_hba.conf";
+	print HBA
+"# TYPE  DATABASE        USER            ADDRESS                 METHOD\n";
+	print HBA
+"hostssl trustdb         ssltestuser     $serverhost/32            trust\n";
+	print HBA
+"hostssl trustdb         ssltestuser     ::1/128                 trust\n";
+	print HBA
+"hostssl certdb          ssltestuser     $serverhost/32            cert\n";
+	print HBA
+"hostssl certdb          ssltestuser     ::1/128                 cert\n";
+	close HBA;
 }
