diff --git a/contrib/passwordcheck/passwordcheck.c b/contrib/passwordcheck/passwordcheck.c
index c988bf5169b95df00ac2577e8b7414856d385615..59f73a1e6ba0b28148d22c7ec63f1bb0e8877d95 100644
--- a/contrib/passwordcheck/passwordcheck.c
+++ b/contrib/passwordcheck/passwordcheck.c
@@ -39,8 +39,8 @@ extern void _PG_init(void);
  *
  * username: name of role being created or changed
  * password: new password (possibly already encrypted)
- * password_type: PASSWORD_TYPE_PLAINTEXT or PASSWORD_TYPE_MD5 (there
- *			could be other encryption schemes in future)
+ * password_type: PASSWORD_TYPE_* code, to indicate if the password is
+ *			in plaintext or encrypted form.
  * validuntil_time: password expiration time, as a timestamptz Datum
  * validuntil_null: true if password expiration time is NULL
  *
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 0b9e3002fb64f6ad113ca6926aa2da85669c9c6c..20bc3c61b12e48339dccb549e02c2f3fabfde6ae 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -1188,14 +1188,16 @@ include_dir 'conf.d'
       <listitem>
        <para>
         When a password is specified in <xref linkend="sql-createrole"> or
-        <xref linkend="sql-alterrole"> without writing either <literal>ENCRYPTED</>
-        or <literal>UNENCRYPTED</>, this parameter determines whether the
-        password is to be encrypted. The default value is <literal>md5</>, which
-        stores the password as an MD5 hash. Setting this to <literal>plain</> stores
-        it in plaintext. <literal>on</> and <literal>off</> are also accepted, as
-        aliases for <literal>md5</> and <literal>plain</>, respectively.  Setting
-        this parameter to <literal>scram-sha-256</> will encrypt the password
-        with SCRAM-SHA-256.
+        <xref linkend="sql-alterrole">, this parameter determines the algorithm
+        to use to encrypt the password. The default value is <literal>md5</>,
+        which stores the password as an MD5 hash (<literal>on</> is also
+        accepted, as alias for <literal>md5</>). Setting this parameter to
+        <literal>scram-sha-256</> will encrypt the password with SCRAM-SHA-256.
+       </para>
+       <para>
+        Note that older clients might lack support for the SCRAM authentication
+        mechanism, and hence not work with passwords encrypted with
+        SCRAM-SHA-256.
        </para>
       </listitem>
      </varlistentry>
diff --git a/doc/src/sgml/ref/alter_role.sgml b/doc/src/sgml/ref/alter_role.sgml
index 37fcfb926c11169f0ce0584046c58e2b86b84182..8cd8602bc4f692adc17f99e11a4740477e18646f 100644
--- a/doc/src/sgml/ref/alter_role.sgml
+++ b/doc/src/sgml/ref/alter_role.sgml
@@ -33,7 +33,7 @@ ALTER ROLE <replaceable class="PARAMETER">role_specification</replaceable> [ WIT
     | REPLICATION | NOREPLICATION
     | BYPASSRLS | NOBYPASSRLS
     | CONNECTION LIMIT <replaceable class="PARAMETER">connlimit</replaceable>
-    | [ ENCRYPTED | UNENCRYPTED ] PASSWORD '<replaceable class="PARAMETER">password</replaceable>'
+    | [ ENCRYPTED ] PASSWORD '<replaceable class="PARAMETER">password</replaceable>'
     | VALID UNTIL '<replaceable class="PARAMETER">timestamp</replaceable>'
 
 ALTER ROLE <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
@@ -168,9 +168,7 @@ ALTER ROLE { <replaceable class="PARAMETER">role_specification</replaceable> | A
       <term><literal>BYPASSRLS</literal></term>
       <term><literal>NOBYPASSRLS</literal></term>
       <term><literal>CONNECTION LIMIT</literal> <replaceable class="parameter">connlimit</replaceable></term>
-      <term><literal>PASSWORD</> <replaceable class="parameter">password</replaceable></term>
-      <term><literal>ENCRYPTED</></term>
-      <term><literal>UNENCRYPTED</></term>
+      <term>[ <literal>ENCRYPTED</> ] <literal>PASSWORD</> <replaceable class="parameter">password</replaceable></term>
       <term><literal>VALID UNTIL</literal> '<replaceable class="parameter">timestamp</replaceable>'</term>
       <listitem>
        <para>
diff --git a/doc/src/sgml/ref/alter_user.sgml b/doc/src/sgml/ref/alter_user.sgml
index 5962a8e166c6f0fa8fce791a10c47d6d342f23ca..9b8a39b37681209700f207e123806ea0833d9edb 100644
--- a/doc/src/sgml/ref/alter_user.sgml
+++ b/doc/src/sgml/ref/alter_user.sgml
@@ -33,7 +33,7 @@ ALTER USER <replaceable class="PARAMETER">role_specification</replaceable> [ WIT
     | REPLICATION | NOREPLICATION
     | BYPASSRLS | NOBYPASSRLS
     | CONNECTION LIMIT <replaceable class="PARAMETER">connlimit</replaceable>
-    | [ ENCRYPTED | UNENCRYPTED ] PASSWORD '<replaceable class="PARAMETER">password</replaceable>'
+    | [ ENCRYPTED ] PASSWORD '<replaceable class="PARAMETER">password</replaceable>'
     | VALID UNTIL '<replaceable class="PARAMETER">timestamp</replaceable>'
 
 ALTER USER <replaceable class="PARAMETER">name</replaceable> RENAME TO <replaceable>new_name</replaceable>
diff --git a/doc/src/sgml/ref/create_group.sgml b/doc/src/sgml/ref/create_group.sgml
index 1d5cc9b5969842985fc657c27d3becd3a3f6af0e..158617cb9391c9af84c34df19eedb9df39083f5a 100644
--- a/doc/src/sgml/ref/create_group.sgml
+++ b/doc/src/sgml/ref/create_group.sgml
@@ -30,7 +30,7 @@ CREATE GROUP <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <repla
     | CREATEROLE | NOCREATEROLE
     | INHERIT | NOINHERIT
     | LOGIN | NOLOGIN
-    | [ ENCRYPTED | UNENCRYPTED ] PASSWORD '<replaceable class="PARAMETER">password</replaceable>'
+    | [ ENCRYPTED ] PASSWORD '<replaceable class="PARAMETER">password</replaceable>'
     | VALID UNTIL '<replaceable class="PARAMETER">timestamp</replaceable>'
     | IN ROLE <replaceable class="PARAMETER">role_name</replaceable> [, ...]
     | IN GROUP <replaceable class="PARAMETER">role_name</replaceable> [, ...]
diff --git a/doc/src/sgml/ref/create_role.sgml b/doc/src/sgml/ref/create_role.sgml
index 99d1c8336c405f67380dd0097012d298ffd0f4e0..43f2303b4817686ec761de016678b4f58f408ff6 100644
--- a/doc/src/sgml/ref/create_role.sgml
+++ b/doc/src/sgml/ref/create_role.sgml
@@ -33,7 +33,7 @@ CREATE ROLE <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <replac
     | REPLICATION | NOREPLICATION
     | BYPASSRLS | NOBYPASSRLS
     | CONNECTION LIMIT <replaceable class="PARAMETER">connlimit</replaceable>
-    | [ ENCRYPTED | UNENCRYPTED ] PASSWORD '<replaceable class="PARAMETER">password</replaceable>'
+    | [ ENCRYPTED ] PASSWORD '<replaceable class="PARAMETER">password</replaceable>'
     | VALID UNTIL '<replaceable class="PARAMETER">timestamp</replaceable>'
     | IN ROLE <replaceable class="PARAMETER">role_name</replaceable> [, ...]
     | IN GROUP <replaceable class="PARAMETER">role_name</replaceable> [, ...]
@@ -207,7 +207,7 @@ CREATE ROLE <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <replac
      </varlistentry>
 
      <varlistentry>
-      <term><literal>PASSWORD</> <replaceable class="parameter">password</replaceable></term>
+      <term>[ <literal>ENCRYPTED</> ] <literal>PASSWORD</> <replaceable class="parameter">password</replaceable></term>
       <listitem>
        <para>
         Sets the role's password.  (A password is only of use for
@@ -219,30 +219,18 @@ CREATE ROLE <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <replac
         user.  A null password can optionally be written explicitly as
         <literal>PASSWORD NULL</literal>.
        </para>
-      </listitem>
-     </varlistentry>
-
-     <varlistentry>
-      <term><literal>ENCRYPTED</></term>
-      <term><literal>UNENCRYPTED</></term>
-      <listitem>
        <para>
-        These key words control whether the password is stored
-        encrypted in the system catalogs.  (If neither is specified,
-        the default behavior is determined by the configuration
-        parameter <xref linkend="guc-password-encryption">.)  If the
-        presented password string is already in MD5-encrypted or
-        SCRAM-encrypted format, then it is stored encrypted as-is,
-        regardless of whether <literal>ENCRYPTED</> or <literal>UNENCRYPTED</>
-        is specified (since the system cannot decrypt the specified encrypted
-        password string).  This allows reloading of encrypted passwords
+        The password is always stored encrypted in the system catalogs. The
+        <literal>ENCRYPTED</> keyword has no effect, but is accepted for
+        backwards compatibility. The method of encryption is determined
+        by the configuration parameter <xref linkend="guc-password-encryption">.
+        If the presented password string is already in MD5-encrypted or
+        SCRAM-encrypted format, then it is stored as-is regardless of
+        <varname>password_encryption</> (since the system cannot decrypt
+        the specified encrypted password string, to encrypt it in a
+        different format).  This allows reloading of encrypted passwords
         during dump/restore.
        </para>
-
-       <para>
-        Note that older clients might lack support for the SCRAM
-        authentication mechanism.
-       </para>
       </listitem>
      </varlistentry>
 
diff --git a/doc/src/sgml/ref/create_user.sgml b/doc/src/sgml/ref/create_user.sgml
index 574604f796d7a55211fdad7d24f2ae72918869b0..8a596eec9f2511ca2768fdb9cab68f7e3162975a 100644
--- a/doc/src/sgml/ref/create_user.sgml
+++ b/doc/src/sgml/ref/create_user.sgml
@@ -33,7 +33,7 @@ CREATE USER <replaceable class="PARAMETER">name</replaceable> [ [ WITH ] <replac
     | REPLICATION | NOREPLICATION
     | BYPASSRLS | NOBYPASSRLS
     | CONNECTION LIMIT <replaceable class="PARAMETER">connlimit</replaceable>
-    | [ ENCRYPTED | UNENCRYPTED ] PASSWORD '<replaceable class="PARAMETER">password</replaceable>'
+    | [ ENCRYPTED ] PASSWORD '<replaceable class="PARAMETER">password</replaceable>'
     | VALID UNTIL '<replaceable class="PARAMETER">timestamp</replaceable>'
     | IN ROLE <replaceable class="PARAMETER">role_name</replaceable> [, ...]
     | IN GROUP <replaceable class="PARAMETER">role_name</replaceable> [, ...]
diff --git a/doc/src/sgml/ref/createuser.sgml b/doc/src/sgml/ref/createuser.sgml
index 4332008c68bd69d1192d730d5cf1d66b4d147ca8..fda77976ff29f479a8154b70fffb55041fc10d18 100644
--- a/doc/src/sgml/ref/createuser.sgml
+++ b/doc/src/sgml/ref/createuser.sgml
@@ -124,8 +124,8 @@ PostgreSQL documentation
       <term><option>--encrypted</></term>
       <listitem>
        <para>
-        Encrypts the user's password stored in the database. If not
-        specified, the default password behavior is used.
+        This option is obsolete but still accepted for backward
+        compatibility.
        </para>
       </listitem>
      </varlistentry>
@@ -204,17 +204,6 @@ PostgreSQL documentation
       </listitem>
      </varlistentry>
 
-     <varlistentry>
-      <term><option>-N</></term>
-      <term><option>--unencrypted</></term>
-      <listitem>
-       <para>
-        Does not encrypt the user's password stored in the database. If
-        not specified, the default password behavior is used.
-       </para>
-      </listitem>
-     </varlistentry>
-
      <varlistentry>
       <term><option>-P</></term>
       <term><option>--pwprompt</></term>
@@ -481,11 +470,7 @@ PostgreSQL documentation
 </screen>
     In the above example, the new password isn't actually echoed when typed,
     but we show what was typed for clarity.  As you see, the password is
-    encrypted before it is sent to the client.  If the option <option>--unencrypted</option>
-    is used, the password <emphasis>will</> appear in the echoed command
-    (and possibly also in the server log and elsewhere),
-    so you don't want to use <option>-e</> in that case, if
-    anyone else can see your screen.
+    encrypted before it is sent to the client.
    </para>
  </refsect1>
 
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index c719682274dff70079f6b6357ba1d5ee5155bc13..36d5f40f0626d572f81c39712dee49ea85af88bb 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -80,7 +80,6 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 	ListCell   *item;
 	ListCell   *option;
 	char	   *password = NULL;	/* user password */
-	int			password_type = Password_encryption;
 	bool		issuper = false;	/* Make the user a superuser? */
 	bool		inherit = true; /* Auto inherit privileges? */
 	bool		createrole = false;		/* Can this user create roles? */
@@ -128,9 +127,7 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 	{
 		DefElem    *defel = (DefElem *) lfirst(option);
 
-		if (strcmp(defel->defname, "password") == 0 ||
-			strcmp(defel->defname, "encryptedPassword") == 0 ||
-			strcmp(defel->defname, "unencryptedPassword") == 0)
+		if (strcmp(defel->defname, "password") == 0)
 		{
 			if (dpassword)
 				ereport(ERROR,
@@ -138,15 +135,6 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 						 errmsg("conflicting or redundant options"),
 						 parser_errposition(pstate, defel->location)));
 			dpassword = defel;
-			if (strcmp(defel->defname, "encryptedPassword") == 0)
-			{
-				if (Password_encryption == PASSWORD_TYPE_SCRAM_SHA_256)
-					password_type = PASSWORD_TYPE_SCRAM_SHA_256;
-				else
-					password_type = PASSWORD_TYPE_MD5;
-			}
-			else if (strcmp(defel->defname, "unencryptedPassword") == 0)
-				password_type = PASSWORD_TYPE_PLAINTEXT;
 		}
 		else if (strcmp(defel->defname, "sysid") == 0)
 		{
@@ -400,7 +388,8 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 		/* Encrypt the password to the requested format. */
 		char	   *shadow_pass;
 
-		shadow_pass = encrypt_password(password_type, stmt->role, password);
+		shadow_pass = encrypt_password(Password_encryption, stmt->role,
+									   password);
 		new_record[Anum_pg_authid_rolpassword - 1] =
 			CStringGetTextDatum(shadow_pass);
 	}
@@ -503,7 +492,6 @@ AlterRole(AlterRoleStmt *stmt)
 	ListCell   *option;
 	char	   *rolename = NULL;
 	char	   *password = NULL;	/* user password */
-	int			password_type = Password_encryption;
 	int			issuper = -1;	/* Make the user a superuser? */
 	int			inherit = -1;	/* Auto inherit privileges? */
 	int			createrole = -1;	/* Can this user create roles? */
@@ -537,24 +525,13 @@ AlterRole(AlterRoleStmt *stmt)
 	{
 		DefElem    *defel = (DefElem *) lfirst(option);
 
-		if (strcmp(defel->defname, "password") == 0 ||
-			strcmp(defel->defname, "encryptedPassword") == 0 ||
-			strcmp(defel->defname, "unencryptedPassword") == 0)
+		if (strcmp(defel->defname, "password") == 0)
 		{
 			if (dpassword)
 				ereport(ERROR,
 						(errcode(ERRCODE_SYNTAX_ERROR),
 						 errmsg("conflicting or redundant options")));
 			dpassword = defel;
-			if (strcmp(defel->defname, "encryptedPassword") == 0)
-			{
-				if (Password_encryption == PASSWORD_TYPE_SCRAM_SHA_256)
-					password_type = PASSWORD_TYPE_SCRAM_SHA_256;
-				else
-					password_type = PASSWORD_TYPE_MD5;
-			}
-			else if (strcmp(defel->defname, "unencryptedPassword") == 0)
-				password_type = PASSWORD_TYPE_PLAINTEXT;
 		}
 		else if (strcmp(defel->defname, "superuser") == 0)
 		{
@@ -809,7 +786,8 @@ AlterRole(AlterRoleStmt *stmt)
 		/* Encrypt the password to the requested format. */
 		char	   *shadow_pass;
 
-		shadow_pass = encrypt_password(password_type, rolename, password);
+		shadow_pass = encrypt_password(Password_encryption, rolename,
+									   password);
 		new_record[Anum_pg_authid_rolpassword - 1] =
 			CStringGetTextDatum(shadow_pass);
 		new_record_repl[Anum_pg_authid_rolpassword - 1] = true;
diff --git a/src/backend/libpq/auth-scram.c b/src/backend/libpq/auth-scram.c
index 3acc2acfe417aebc2452ce695748184e518fea2f..99feb0ce9477cdafa9919934f5c6a421e55105d4 100644
--- a/src/backend/libpq/auth-scram.c
+++ b/src/backend/libpq/auth-scram.c
@@ -199,27 +199,11 @@ pg_be_scram_init(const char *username, const char *shadow_pass)
 				got_verifier = false;
 			}
 		}
-		else if (password_type == PASSWORD_TYPE_PLAINTEXT)
-		{
-			/*
-			 * The stored password is in plain format.  Generate a fresh SCRAM
-			 * verifier from it, and proceed with that.
-			 */
-			char	   *verifier;
-
-			verifier = pg_be_scram_build_verifier(shadow_pass);
-
-			(void) parse_scram_verifier(verifier, &state->iterations, &state->salt,
-										state->StoredKey, state->ServerKey);
-			pfree(verifier);
-
-			got_verifier = true;
-		}
 		else
 		{
 			/*
-			 * The user doesn't have SCRAM verifier, nor could we generate
-			 * one. (You cannot do SCRAM authentication with an MD5 hash.)
+			 * The user doesn't have SCRAM verifier. (You cannot do SCRAM
+			 * authentication with an MD5 hash.)
 			 */
 			state->logdetail = psprintf(_("User \"%s\" does not have a valid SCRAM verifier."),
 										state->username);
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index ab4be21943121eac599f99cd43343b586692382f..6d3ff68607dcf8e06a4fbb0127917c1d97be4f3d 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -754,17 +754,13 @@ CheckPWChallengeAuth(Port *port, char **logdetail)
 	shadow_pass = get_role_password(port->user_name, logdetail);
 
 	/*
-	 * If the user does not exist, or has no password, we still go through the
-	 * motions of authentication, to avoid revealing to the client that the
-	 * user didn't exist.  If 'md5' is allowed, we choose whether to use 'md5'
-	 * or 'scram-sha-256' authentication based on current password_encryption
-	 * setting.  The idea is that most genuine users probably have a password
-	 * of that type, if we pretend that this user had a password of that type,
-	 * too, it "blends in" best.
-	 *
-	 * If the user had a password, but it was expired, we'll use the details
-	 * of the expired password for the authentication, but report it as
-	 * failure to the client even if correct password was given.
+	 * If the user does not exist, or has no password or it's expired, we
+	 * still go through the motions of authentication, to avoid revealing to
+	 * the client that the user didn't exist.  If 'md5' is allowed, we choose
+	 * whether to use 'md5' or 'scram-sha-256' authentication based on
+	 * current password_encryption setting.  The idea is that most genuine
+	 * users probably have a password of that type, and if we pretend that
+	 * this user had a password of that type, too, it "blends in" best.
 	 */
 	if (!shadow_pass)
 		pwtype = Password_encryption;
@@ -775,21 +771,15 @@ CheckPWChallengeAuth(Port *port, char **logdetail)
 	 * If 'md5' authentication is allowed, decide whether to perform 'md5' or
 	 * 'scram-sha-256' authentication based on the type of password the user
 	 * has.  If it's an MD5 hash, we must do MD5 authentication, and if it's
-	 * a SCRAM verifier, we must do SCRAM authentication.  If it's stored in
-	 * plaintext, we could do either one, so we opt for the more secure
-	 * mechanism, SCRAM.
+	 * a SCRAM verifier, we must do SCRAM authentication.
 	 *
 	 * If MD5 authentication is not allowed, always use SCRAM.  If the user
 	 * had an MD5 password, CheckSCRAMAuth() will fail.
 	 */
 	if (port->hba->auth_method == uaMD5 && pwtype == PASSWORD_TYPE_MD5)
-	{
 		auth_result = CheckMD5Auth(port, shadow_pass, logdetail);
-	}
 	else
-	{
 		auth_result = CheckSCRAMAuth(port, shadow_pass, logdetail);
-	}
 
 	if (shadow_pass)
 		pfree(shadow_pass);
diff --git a/src/backend/libpq/crypt.c b/src/backend/libpq/crypt.c
index 9fe79b48946386bffca7a6fe27c914b5ec9599ef..e7a6b04fb5a549355f9011c81047288c185d459f 100644
--- a/src/backend/libpq/crypt.c
+++ b/src/backend/libpq/crypt.c
@@ -109,9 +109,8 @@ get_password_type(const char *shadow_pass)
  * Given a user-supplied password, convert it into a verifier of
  * 'target_type' kind.
  *
- * If the password looks like a valid MD5 hash, it is stored as it is.
- * We cannot reverse the hash, so even if the caller requested a plaintext
- * plaintext password, the MD5 hash is returned.
+ * If the password is already in encrypted form, we cannot reverse the
+ * hash, so it is stored as it is regardless of the requested type.
  */
 char *
 encrypt_password(PasswordType target_type, const char *role,
@@ -120,54 +119,30 @@ encrypt_password(PasswordType target_type, const char *role,
 	PasswordType guessed_type = get_password_type(password);
 	char	   *encrypted_password;
 
-	switch (target_type)
+	if (guessed_type != PASSWORD_TYPE_PLAINTEXT)
 	{
-		case PASSWORD_TYPE_PLAINTEXT:
-
-			/*
-			 * We cannot convert a hashed password back to plaintext, so just
-			 * store the password as it was, whether it was hashed or not.
-			 */
-			return pstrdup(password);
+		/*
+		 * Cannot convert an already-encrypted password from one
+		 * format to another, so return it as it is.
+		 */
+		return pstrdup(password);
+	}
 
+	switch (target_type)
+	{
 		case PASSWORD_TYPE_MD5:
-			switch (guessed_type)
-			{
-				case PASSWORD_TYPE_PLAINTEXT:
-					encrypted_password = palloc(MD5_PASSWD_LEN + 1);
-
-					if (!pg_md5_encrypt(password, role, strlen(role),
-										encrypted_password))
-						elog(ERROR, "password encryption failed");
-					return encrypted_password;
+			encrypted_password = palloc(MD5_PASSWD_LEN + 1);
 
-				case PASSWORD_TYPE_SCRAM_SHA_256:
-
-					/*
-					 * cannot convert a SCRAM verifier to an MD5 hash, so fall
-					 * through to save the SCRAM verifier instead.
-					 */
-				case PASSWORD_TYPE_MD5:
-					return pstrdup(password);
-			}
-			break;
+			if (!pg_md5_encrypt(password, role, strlen(role),
+								encrypted_password))
+				elog(ERROR, "password encryption failed");
+			return encrypted_password;
 
 		case PASSWORD_TYPE_SCRAM_SHA_256:
-			switch (guessed_type)
-			{
-				case PASSWORD_TYPE_PLAINTEXT:
-					return pg_be_scram_build_verifier(password);
-
-				case PASSWORD_TYPE_MD5:
+			return pg_be_scram_build_verifier(password);
 
-					/*
-					 * cannot convert an MD5 hash to a SCRAM verifier, so fall
-					 * through to save the MD5 hash instead.
-					 */
-				case PASSWORD_TYPE_SCRAM_SHA_256:
-					return pstrdup(password);
-			}
-			break;
+		case PASSWORD_TYPE_PLAINTEXT:
+			elog(ERROR, "cannot encrypt password with 'plaintext'");
 	}
 
 	/*
@@ -197,10 +172,17 @@ md5_crypt_verify(const char *role, const char *shadow_pass,
 {
 	int			retval;
 	char		crypt_pwd[MD5_PASSWD_LEN + 1];
-	char		crypt_pwd2[MD5_PASSWD_LEN + 1];
 
 	Assert(md5_salt_len > 0);
 
+	if (get_password_type(shadow_pass) != PASSWORD_TYPE_MD5)
+	{
+		/* incompatible password hash format. */
+		*logdetail = psprintf(_("User \"%s\" has a password that cannot be used with MD5 authentication."),
+							  role);
+		return STATUS_ERROR;
+	}
+
 	/*
 	 * Compute the correct answer for the MD5 challenge.
 	 *
@@ -208,40 +190,12 @@ md5_crypt_verify(const char *role, const char *shadow_pass,
 	 * below: the only possible error is out-of-memory, which is unlikely, and
 	 * if it did happen adding a psprintf call would only make things worse.
 	 */
-	switch (get_password_type(shadow_pass))
+	/* stored password already encrypted, only do salt */
+	if (!pg_md5_encrypt(shadow_pass + strlen("md5"),
+						md5_salt, md5_salt_len,
+						crypt_pwd))
 	{
-		case PASSWORD_TYPE_MD5:
-			/* stored password already encrypted, only do salt */
-			if (!pg_md5_encrypt(shadow_pass + strlen("md5"),
-								md5_salt, md5_salt_len,
-								crypt_pwd))
-			{
-				return STATUS_ERROR;
-			}
-			break;
-
-		case PASSWORD_TYPE_PLAINTEXT:
-			/* stored password is plain, double-encrypt */
-			if (!pg_md5_encrypt(shadow_pass,
-								role,
-								strlen(role),
-								crypt_pwd2))
-			{
-				return STATUS_ERROR;
-			}
-			if (!pg_md5_encrypt(crypt_pwd2 + strlen("md5"),
-								md5_salt, md5_salt_len,
-								crypt_pwd))
-			{
-				return STATUS_ERROR;
-			}
-			break;
-
-		default:
-			/* unknown password hash format. */
-			*logdetail = psprintf(_("User \"%s\" has a password that cannot be used with MD5 authentication."),
-								  role);
-			return STATUS_ERROR;
+		return STATUS_ERROR;
 	}
 
 	if (strcmp(client_pass, crypt_pwd) == 0)
@@ -259,8 +213,8 @@ md5_crypt_verify(const char *role, const char *shadow_pass,
 /*
  * Check given password for given user, and return STATUS_OK or STATUS_ERROR.
  *
- * 'shadow_pass' is the user's correct password or password hash, as stored
- * in pg_authid.rolpassword.
+ * 'shadow_pass' is the user's correct password hash, as stored in
+ * pg_authid.rolpassword.
  * 'client_pass' is the password given by the remote user.
  *
  * In the error case, optionally store a palloc'd string at *logdetail
@@ -320,14 +274,10 @@ plain_crypt_verify(const char *role, const char *shadow_pass,
 			break;
 
 		case PASSWORD_TYPE_PLAINTEXT:
-			if (strcmp(client_pass, shadow_pass) == 0)
-				return STATUS_OK;
-			else
-			{
-				*logdetail = psprintf(_("Password does not match for user \"%s\"."),
-									  role);
-				return STATUS_ERROR;
-			}
+			/*
+			 * We never store passwords in plaintext, so this shouldn't
+			 * happen.
+			 */
 			break;
 	}
 
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 818d2c29d494710573be3a69a2bc1f904ebea2fb..2cad8b25b8a60ac58257c020f9e0c81840600a24 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -994,13 +994,21 @@ AlterOptRoleElem:
 				}
 			| ENCRYPTED PASSWORD Sconst
 				{
-					$$ = makeDefElem("encryptedPassword",
+					/*
+					 * These days, passwords are always stored in encrypted
+					 * form, so there is no difference between PASSWORD and
+					 * ENCRYPTED PASSWORD.
+					 */
+					$$ = makeDefElem("password",
 									 (Node *)makeString($3), @1);
 				}
 			| UNENCRYPTED PASSWORD Sconst
 				{
-					$$ = makeDefElem("unencryptedPassword",
-									 (Node *)makeString($3), @1);
+					ereport(ERROR,
+							(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+							 errmsg("UNENCRYPTED PASSWORD is no longer supported"),
+							 errhint("Remove UNENCRYPTED to store the password in encrypted form instead."),
+							 parser_errposition(@1)));
 				}
 			| INHERIT
 				{
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 587fbce147fa2f8e151d9852eac4ba9e4cb1943c..cb4e621c8488eb69e550af78d71537d8f83dcb38 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -405,20 +405,16 @@ static const struct config_enum_entry force_parallel_mode_options[] = {
 
 /*
  * password_encryption used to be a boolean, so accept all the likely
- * variants of "on" and "off", too.
+ * variants of "on", too. "off" used to store passwords in plaintext,
+ * but we don't support that anymore.
  */
 static const struct config_enum_entry password_encryption_options[] = {
-	{"plain", PASSWORD_TYPE_PLAINTEXT, false},
 	{"md5", PASSWORD_TYPE_MD5, false},
 	{"scram-sha-256", PASSWORD_TYPE_SCRAM_SHA_256, false},
-	{"off", PASSWORD_TYPE_PLAINTEXT, false},
-	{"on", PASSWORD_TYPE_MD5, false},
+	{"on", PASSWORD_TYPE_MD5, true},
 	{"true", PASSWORD_TYPE_MD5, true},
-	{"false", PASSWORD_TYPE_PLAINTEXT, true},
 	{"yes", PASSWORD_TYPE_MD5, true},
-	{"no", PASSWORD_TYPE_PLAINTEXT, true},
 	{"1", PASSWORD_TYPE_MD5, true},
-	{"0", PASSWORD_TYPE_PLAINTEXT, true},
 	{NULL, 0, false}
 };
 
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index e2a335121043363c6e9bf1fb0b58f6c6e52ad088..183fc376296e5cc05b81f225f1f27e2eaf3a01e1 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -1634,10 +1634,10 @@ psql_completion(const char *text, int start, int end)
 	{
 		static const char *const list_ALTERUSER[] =
 		{"BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
-			"ENCRYPTED", "INHERIT", "LOGIN", "NOBYPASSRLS",
+			"ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS",
 			"NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
 			"NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", "RENAME TO",
-			"REPLICATION", "RESET", "SET", "SUPERUSER", "UNENCRYPTED",
+			"REPLICATION", "RESET", "SET", "SUPERUSER",
 		"VALID UNTIL", "WITH", NULL};
 
 		COMPLETE_WITH_LIST(list_ALTERUSER);
@@ -1649,18 +1649,15 @@ psql_completion(const char *text, int start, int end)
 		/* Similar to the above, but don't complete "WITH" again. */
 		static const char *const list_ALTERUSER_WITH[] =
 		{"BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
-			"ENCRYPTED", "INHERIT", "LOGIN", "NOBYPASSRLS",
+			"ENCRYPTED PASSWORD", "INHERIT", "LOGIN", "NOBYPASSRLS",
 			"NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
 			"NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD", "RENAME TO",
-			"REPLICATION", "RESET", "SET", "SUPERUSER", "UNENCRYPTED",
+			"REPLICATION", "RESET", "SET", "SUPERUSER",
 		"VALID UNTIL", NULL};
 
 		COMPLETE_WITH_LIST(list_ALTERUSER_WITH);
 	}
 
-	/* complete ALTER USER,ROLE <name> ENCRYPTED,UNENCRYPTED with PASSWORD */
-	else if (Matches4("ALTER", "USER|ROLE", MatchAny, "ENCRYPTED|UNENCRYPTED"))
-		COMPLETE_WITH_CONST("PASSWORD");
 	/* ALTER DEFAULT PRIVILEGES */
 	else if (Matches3("ALTER", "DEFAULT", "PRIVILEGES"))
 		COMPLETE_WITH_LIST2("FOR ROLE", "IN SCHEMA");
@@ -2502,10 +2499,10 @@ psql_completion(const char *text, int start, int end)
 	{
 		static const char *const list_CREATEROLE[] =
 		{"ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
-			"ENCRYPTED", "IN", "INHERIT", "LOGIN", "NOBYPASSRLS",
+			"ENCRYPTED PASSWORD", "IN", "INHERIT", "LOGIN", "NOBYPASSRLS",
 			"NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
 			"NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
-			"REPLICATION", "ROLE", "SUPERUSER", "SYSID", "UNENCRYPTED",
+			"REPLICATION", "ROLE", "SUPERUSER", "SYSID",
 		"VALID UNTIL", "WITH", NULL};
 
 		COMPLETE_WITH_LIST(list_CREATEROLE);
@@ -2517,21 +2514,15 @@ psql_completion(const char *text, int start, int end)
 		/* Similar to the above, but don't complete "WITH" again. */
 		static const char *const list_CREATEROLE_WITH[] =
 		{"ADMIN", "BYPASSRLS", "CONNECTION LIMIT", "CREATEDB", "CREATEROLE",
-			"ENCRYPTED", "IN", "INHERIT", "LOGIN", "NOBYPASSRLS",
+			"ENCRYPTED PASSWORD", "IN", "INHERIT", "LOGIN", "NOBYPASSRLS",
 			"NOCREATEDB", "NOCREATEROLE", "NOINHERIT",
 			"NOLOGIN", "NOREPLICATION", "NOSUPERUSER", "PASSWORD",
-			"REPLICATION", "ROLE", "SUPERUSER", "SYSID", "UNENCRYPTED",
+			"REPLICATION", "ROLE", "SUPERUSER", "SYSID",
 		"VALID UNTIL", NULL};
 
 		COMPLETE_WITH_LIST(list_CREATEROLE_WITH);
 	}
 
-	/*
-	 * complete CREATE ROLE,USER,GROUP <name> ENCRYPTED,UNENCRYPTED with
-	 * PASSWORD
-	 */
-	else if (Matches4("CREATE", "ROLE|USER|GROUP", MatchAny, "ENCRYPTED|UNENCRYPTED"))
-		COMPLETE_WITH_CONST("PASSWORD");
 	/* complete CREATE ROLE,USER,GROUP <name> IN with ROLE,GROUP */
 	else if (Matches4("CREATE", "ROLE|USER|GROUP", MatchAny, "IN"))
 		COMPLETE_WITH_LIST2("GROUP", "ROLE");
diff --git a/src/bin/scripts/createuser.c b/src/bin/scripts/createuser.c
index 35a53bf2064d9bde325d940e6c454322d7b347cb..d88093f8b6e9e80bf6c9e93e332ffde26eea1669 100644
--- a/src/bin/scripts/createuser.c
+++ b/src/bin/scripts/createuser.c
@@ -48,7 +48,6 @@ main(int argc, char *argv[])
 		{"connection-limit", required_argument, NULL, 'c'},
 		{"pwprompt", no_argument, NULL, 'P'},
 		{"encrypted", no_argument, NULL, 'E'},
-		{"unencrypted", no_argument, NULL, 'N'},
 		{NULL, 0, NULL, 0}
 	};
 
@@ -75,8 +74,7 @@ main(int argc, char *argv[])
 				createrole = TRI_DEFAULT,
 				inherit = TRI_DEFAULT,
 				login = TRI_DEFAULT,
-				replication = TRI_DEFAULT,
-				encrypted = TRI_DEFAULT;
+				replication = TRI_DEFAULT;
 
 	PQExpBufferData sql;
 
@@ -88,7 +86,7 @@ main(int argc, char *argv[])
 
 	handle_help_version_opts(argc, argv, "createuser", help);
 
-	while ((c = getopt_long(argc, argv, "h:p:U:g:wWedDsSaArRiIlLc:PEN",
+	while ((c = getopt_long(argc, argv, "h:p:U:g:wWedDsSaArRiIlLc:PE",
 							long_options, &optindex)) != -1)
 	{
 		switch (c)
@@ -153,10 +151,7 @@ main(int argc, char *argv[])
 				pwprompt = true;
 				break;
 			case 'E':
-				encrypted = TRI_YES;
-				break;
-			case 'N':
-				encrypted = TRI_NO;
+				/* no-op, accepted for backward compatibility */
 				break;
 			case 1:
 				replication = TRI_YES;
@@ -264,31 +259,22 @@ main(int argc, char *argv[])
 	printfPQExpBuffer(&sql, "CREATE ROLE %s", fmtId(newuser));
 	if (newpassword)
 	{
-		if (encrypted == TRI_YES)
-			appendPQExpBufferStr(&sql, " ENCRYPTED");
-		if (encrypted == TRI_NO)
-			appendPQExpBufferStr(&sql, " UNENCRYPTED");
+		char	   *encrypted_password;
+
 		appendPQExpBufferStr(&sql, " PASSWORD ");
 
-		if (encrypted != TRI_NO)
+		encrypted_password = PQencryptPasswordConn(conn,
+												   newpassword,
+												   newuser,
+												   NULL);
+		if (!encrypted_password)
 		{
-			char	   *encrypted_password;
-
-			encrypted_password = PQencryptPasswordConn(conn,
-													   newpassword,
-													   newuser,
-													   NULL);
-			if (!encrypted_password)
-			{
-				fprintf(stderr, _("%s: password encryption failed: %s"),
-						progname, PQerrorMessage(conn));
-				exit(1);
-			}
-			appendStringLiteralConn(&sql, encrypted_password, conn);
-			PQfreemem(encrypted_password);
+			fprintf(stderr, _("%s: password encryption failed: %s"),
+					progname, PQerrorMessage(conn));
+			exit(1);
 		}
-		else
-			appendStringLiteralConn(&sql, newpassword, conn);
+		appendStringLiteralConn(&sql, encrypted_password, conn);
+		PQfreemem(encrypted_password);
 	}
 	if (superuser == TRI_YES)
 		appendPQExpBufferStr(&sql, " SUPERUSER");
@@ -361,14 +347,12 @@ help(const char *progname)
 	printf(_("  -d, --createdb            role can create new databases\n"));
 	printf(_("  -D, --no-createdb         role cannot create databases (default)\n"));
 	printf(_("  -e, --echo                show the commands being sent to the server\n"));
-	printf(_("  -E, --encrypted           encrypt stored password\n"));
 	printf(_("  -g, --role=ROLE           new role will be a member of this role\n"));
 	printf(_("  -i, --inherit             role inherits privileges of roles it is a\n"
 			 "                            member of (default)\n"));
 	printf(_("  -I, --no-inherit          role does not inherit privileges\n"));
 	printf(_("  -l, --login               role can login (default)\n"));
 	printf(_("  -L, --no-login            role cannot login\n"));
-	printf(_("  -N, --unencrypted         do not encrypt stored password\n"));
 	printf(_("  -P, --pwprompt            assign a password to new role\n"));
 	printf(_("  -r, --createrole          role can create new roles\n"));
 	printf(_("  -R, --no-createrole       role cannot create roles (default)\n"));
diff --git a/src/include/libpq/crypt.h b/src/include/libpq/crypt.h
index 63724f39ee2044f916f3ad6e81295c88ee59493a..9bad67c89021467f1315e5e4bd00bacfad5607bb 100644
--- a/src/include/libpq/crypt.h
+++ b/src/include/libpq/crypt.h
@@ -16,10 +16,13 @@
 #include "datatype/timestamp.h"
 
 /*
- * Types of password hashes or verifiers that can be stored in
- * pg_authid.rolpassword.
+ * Types of password hashes or verifiers.
  *
- * This is also used for the password_encryption GUC.
+ * Plaintext passwords can be passed in by the user, in a CREATE/ALTER USER
+ * command. They will be encrypted to MD5 or SCRAM-SHA-256 format, before
+ * storing on-disk, so only MD5 and SCRAM-SHA-256 passwords should appear
+ * in pg_authid.rolpassword. They are also the allowed values for the
+ * password_encryption GUC.
  */
 typedef enum PasswordType
 {
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
index 54acd0f6bf8694be0827b45ae95a486fc0cc5b4a..f4397afc64901bd30bdfafb7489e544e4d078def 100644
--- a/src/interfaces/libpq/fe-auth.c
+++ b/src/interfaces/libpq/fe-auth.c
@@ -1183,8 +1183,7 @@ PQencryptPasswordConn(PGconn *conn, const char *passwd, const char *user,
 	 * send the password in plaintext even if it was "off".
 	 */
 	if (strcmp(algorithm, "on") == 0 ||
-		strcmp(algorithm, "off") == 0 ||
-		strcmp(algorithm, "plain") == 0)
+		strcmp(algorithm, "off") == 0)
 		algorithm = "md5";
 
 	/*
diff --git a/src/test/authentication/t/001_password.pl b/src/test/authentication/t/001_password.pl
index 216bdc031c81c9e46c246a60f8885fb9e6ef749a..5a21ecd7e66f027446c53cbbe6cf2bb8bf291412 100644
--- a/src/test/authentication/t/001_password.pl
+++ b/src/test/authentication/t/001_password.pl
@@ -10,7 +10,7 @@ use strict;
 use warnings;
 use PostgresNode;
 use TestLib;
-use Test::More tests => 12;
+use Test::More tests => 8;
 
 # Delete pg_hba.conf from the given node, add a new entry to it
 # and then execute a reload to refresh it.
@@ -53,32 +53,26 @@ SKIP:
 	# password is used for all of them.
 	$node->safe_psql('postgres', "SET password_encryption='scram-sha-256'; CREATE ROLE scram_role LOGIN PASSWORD 'pass';");
 	$node->safe_psql('postgres', "SET password_encryption='md5'; CREATE ROLE md5_role LOGIN PASSWORD 'pass';");
-	$node->safe_psql('postgres', "SET password_encryption='plain'; CREATE ROLE plain_role LOGIN PASSWORD 'pass';");
 	$ENV{"PGPASSWORD"} = 'pass';
 
 	# For "trust" method, all users should be able to connect.
 	reset_pg_hba($node, 'trust');
 	test_role($node, 'scram_role', 'trust', 0);
 	test_role($node, 'md5_role', 'trust', 0);
-	test_role($node, 'plain_role', 'trust', 0);
 
 	# For plain "password" method, all users should also be able to connect.
 	reset_pg_hba($node, 'password');
 	test_role($node, 'scram_role', 'password', 0);
 	test_role($node, 'md5_role', 'password', 0);
-	test_role($node, 'plain_role', 'password', 0);
 
-	# For "scram-sha-256" method, user "plain_role" and "scram_role" should
-	# be able to connect.
+	# For "scram-sha-256" method, user "scram_role" should be able to connect.
 	reset_pg_hba($node, 'scram-sha-256');
 	test_role($node, 'scram_role', 'scram-sha-256', 0);
 	test_role($node, 'md5_role', 'scram-sha-256', 2);
-	test_role($node, 'plain_role', 'scram-sha-256', 0);
 
 	# For "md5" method, all users should be able to connect (SCRAM
 	# authentication will be performed for the user with a scram verifier.)
 	reset_pg_hba($node, 'md5');
 	test_role($node, 'scram_role', 'md5', 0);
 	test_role($node, 'md5_role', 'md5', 0);
-	test_role($node, 'plain_role', 'md5', 0);
 }
diff --git a/src/test/regress/expected/password.out b/src/test/regress/expected/password.out
index 5b0b955b29bbaeeee168fbcffdd9ff6f998255f2..bb25ad0c2cfb21508fc8920d60c5dc3fbc7d5966 100644
--- a/src/test/regress/expected/password.out
+++ b/src/test/regress/expected/password.out
@@ -4,22 +4,18 @@
 -- Tests for GUC password_encryption
 SET password_encryption = 'novalue'; -- error
 ERROR:  invalid value for parameter "password_encryption": "novalue"
-HINT:  Available values: plain, md5, scram-sha-256, off, on.
+HINT:  Available values: md5, scram-sha-256.
 SET password_encryption = true; -- ok
 SET password_encryption = 'md5'; -- ok
-SET password_encryption = 'plain'; -- ok
 SET password_encryption = 'scram-sha-256'; -- ok
 -- consistency of password entries
-SET password_encryption = 'plain';
-CREATE ROLE regress_passwd1 PASSWORD 'role_pwd1';
 SET password_encryption = 'md5';
-CREATE ROLE regress_passwd2 PASSWORD 'role_pwd2';
+CREATE ROLE regress_passwd1 PASSWORD 'role_pwd1';
 SET password_encryption = 'on';
-CREATE ROLE regress_passwd3 PASSWORD 'role_pwd3';
+CREATE ROLE regress_passwd2 PASSWORD 'role_pwd2';
 SET password_encryption = 'scram-sha-256';
-CREATE ROLE regress_passwd4 PASSWORD 'role_pwd4';
-SET password_encryption = 'plain';
-CREATE ROLE regress_passwd5 PASSWORD NULL;
+CREATE ROLE regress_passwd3 PASSWORD 'role_pwd3';
+CREATE ROLE regress_passwd4 PASSWORD NULL;
 -- check list of created entries
 --
 -- The scram verifier will look something like:
@@ -33,56 +29,57 @@ SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+
     ORDER BY rolname, rolpassword;
      rolname     |                rolpassword_masked                 
 -----------------+---------------------------------------------------
- regress_passwd1 | role_pwd1
+ regress_passwd1 | md5783277baca28003b33453252be4dbb34
  regress_passwd2 | md54044304ba511dd062133eb5b4b84a2a3
- regress_passwd3 | md50e5699b6911d87f17a08b8d76a21e8b8
- regress_passwd4 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey>
- regress_passwd5 | 
-(5 rows)
+ regress_passwd3 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey>
+ regress_passwd4 | 
+(4 rows)
 
 -- Rename a role
-ALTER ROLE regress_passwd3 RENAME TO regress_passwd3_new;
+ALTER ROLE regress_passwd2 RENAME TO regress_passwd2_new;
 NOTICE:  MD5 password cleared because of role rename
 -- md5 entry should have been removed
 SELECT rolname, rolpassword
     FROM pg_authid
-    WHERE rolname LIKE 'regress_passwd3_new'
+    WHERE rolname LIKE 'regress_passwd2_new'
     ORDER BY rolname, rolpassword;
        rolname       | rolpassword 
 ---------------------+-------------
- regress_passwd3_new | 
+ regress_passwd2_new | 
 (1 row)
 
-ALTER ROLE regress_passwd3_new RENAME TO regress_passwd3;
--- ENCRYPTED and UNENCRYPTED passwords
-ALTER ROLE regress_passwd1 UNENCRYPTED PASSWORD 'foo'; -- unencrypted
-ALTER ROLE regress_passwd2 UNENCRYPTED PASSWORD 'md5dfa155cadd5f4ad57860162f3fab9cdb'; -- encrypted with MD5
+ALTER ROLE regress_passwd2_new RENAME TO regress_passwd2;
+-- Change passwords with ALTER USER. With plaintext or already-encrypted
+-- passwords.
 SET password_encryption = 'md5';
-ALTER ROLE regress_passwd3 ENCRYPTED PASSWORD 'foo'; -- encrypted with MD5
-ALTER ROLE regress_passwd4 ENCRYPTED PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo='; -- client-supplied SCRAM verifier, use as it is
+-- encrypt with MD5
+ALTER ROLE regress_passwd2 PASSWORD 'foo';
+-- already encrypted, use as they are
+ALTER ROLE regress_passwd1 PASSWORD 'md5cd3578025fe2c3d7ed1b9a9b26238b70';
+ALTER ROLE regress_passwd3 PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo=';
 SET password_encryption = 'scram-sha-256';
-ALTER ROLE  regress_passwd5 ENCRYPTED PASSWORD 'foo'; -- create SCRAM verifier
-CREATE ROLE regress_passwd6 ENCRYPTED PASSWORD 'md53725413363ab045e20521bf36b8d8d7f'; -- encrypted with MD5, use as it is
+-- create SCRAM verifier
+ALTER ROLE  regress_passwd4 PASSWORD 'foo';
+-- already encrypted with MD5, use as it is
+CREATE ROLE regress_passwd5 PASSWORD 'md5e73a4b11df52a6068f8b39f90be36023';
 SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/=]+)\$([a-zA-Z0-9+=/]+):([a-zA-Z0-9+/=]+)', '\1$\2:<salt>$<storedkey>:<serverkey>') as rolpassword_masked
     FROM pg_authid
     WHERE rolname LIKE 'regress_passwd%'
     ORDER BY rolname, rolpassword;
      rolname     |                rolpassword_masked                 
 -----------------+---------------------------------------------------
- regress_passwd1 | foo
+ regress_passwd1 | md5cd3578025fe2c3d7ed1b9a9b26238b70
  regress_passwd2 | md5dfa155cadd5f4ad57860162f3fab9cdb
- regress_passwd3 | md5530de4c298af94b3b9f7d20305d2a1bf
+ regress_passwd3 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey>
  regress_passwd4 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey>
- regress_passwd5 | SCRAM-SHA-256$4096:<salt>$<storedkey>:<serverkey>
- regress_passwd6 | md53725413363ab045e20521bf36b8d8d7f
-(6 rows)
+ regress_passwd5 | md5e73a4b11df52a6068f8b39f90be36023
+(5 rows)
 
 DROP ROLE regress_passwd1;
 DROP ROLE regress_passwd2;
 DROP ROLE regress_passwd3;
 DROP ROLE regress_passwd4;
 DROP ROLE regress_passwd5;
-DROP ROLE regress_passwd6;
 -- all entries should have been removed
 SELECT rolname, rolpassword
     FROM pg_authid
diff --git a/src/test/regress/sql/password.sql b/src/test/regress/sql/password.sql
index d2e9eea79d2a207094f8f01f8a6bb82b4d5ff101..f16824372541642eeddb572debe608f149bdd918 100644
--- a/src/test/regress/sql/password.sql
+++ b/src/test/regress/sql/password.sql
@@ -6,20 +6,16 @@
 SET password_encryption = 'novalue'; -- error
 SET password_encryption = true; -- ok
 SET password_encryption = 'md5'; -- ok
-SET password_encryption = 'plain'; -- ok
 SET password_encryption = 'scram-sha-256'; -- ok
 
 -- consistency of password entries
-SET password_encryption = 'plain';
-CREATE ROLE regress_passwd1 PASSWORD 'role_pwd1';
 SET password_encryption = 'md5';
-CREATE ROLE regress_passwd2 PASSWORD 'role_pwd2';
+CREATE ROLE regress_passwd1 PASSWORD 'role_pwd1';
 SET password_encryption = 'on';
-CREATE ROLE regress_passwd3 PASSWORD 'role_pwd3';
+CREATE ROLE regress_passwd2 PASSWORD 'role_pwd2';
 SET password_encryption = 'scram-sha-256';
-CREATE ROLE regress_passwd4 PASSWORD 'role_pwd4';
-SET password_encryption = 'plain';
-CREATE ROLE regress_passwd5 PASSWORD NULL;
+CREATE ROLE regress_passwd3 PASSWORD 'role_pwd3';
+CREATE ROLE regress_passwd4 PASSWORD NULL;
 
 -- check list of created entries
 --
@@ -34,25 +30,29 @@ SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+
     ORDER BY rolname, rolpassword;
 
 -- Rename a role
-ALTER ROLE regress_passwd3 RENAME TO regress_passwd3_new;
+ALTER ROLE regress_passwd2 RENAME TO regress_passwd2_new;
 -- md5 entry should have been removed
 SELECT rolname, rolpassword
     FROM pg_authid
-    WHERE rolname LIKE 'regress_passwd3_new'
+    WHERE rolname LIKE 'regress_passwd2_new'
     ORDER BY rolname, rolpassword;
-ALTER ROLE regress_passwd3_new RENAME TO regress_passwd3;
+ALTER ROLE regress_passwd2_new RENAME TO regress_passwd2;
 
--- ENCRYPTED and UNENCRYPTED passwords
-ALTER ROLE regress_passwd1 UNENCRYPTED PASSWORD 'foo'; -- unencrypted
-ALTER ROLE regress_passwd2 UNENCRYPTED PASSWORD 'md5dfa155cadd5f4ad57860162f3fab9cdb'; -- encrypted with MD5
+-- Change passwords with ALTER USER. With plaintext or already-encrypted
+-- passwords.
 SET password_encryption = 'md5';
-ALTER ROLE regress_passwd3 ENCRYPTED PASSWORD 'foo'; -- encrypted with MD5
 
-ALTER ROLE regress_passwd4 ENCRYPTED PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo='; -- client-supplied SCRAM verifier, use as it is
+-- encrypt with MD5
+ALTER ROLE regress_passwd2 PASSWORD 'foo';
+-- already encrypted, use as they are
+ALTER ROLE regress_passwd1 PASSWORD 'md5cd3578025fe2c3d7ed1b9a9b26238b70';
+ALTER ROLE regress_passwd3 PASSWORD 'SCRAM-SHA-256$4096:VLK4RMaQLCvNtQ==$6YtlR4t69SguDiwFvbVgVZtuz6gpJQQqUMZ7IQJK5yI=:ps75jrHeYU4lXCcXI4O8oIdJ3eO8o2jirjruw9phBTo=';
 
 SET password_encryption = 'scram-sha-256';
-ALTER ROLE  regress_passwd5 ENCRYPTED PASSWORD 'foo'; -- create SCRAM verifier
-CREATE ROLE regress_passwd6 ENCRYPTED PASSWORD 'md53725413363ab045e20521bf36b8d8d7f'; -- encrypted with MD5, use as it is
+-- create SCRAM verifier
+ALTER ROLE  regress_passwd4 PASSWORD 'foo';
+-- already encrypted with MD5, use as it is
+CREATE ROLE regress_passwd5 PASSWORD 'md5e73a4b11df52a6068f8b39f90be36023';
 
 SELECT rolname, regexp_replace(rolpassword, '(SCRAM-SHA-256)\$(\d+):([a-zA-Z0-9+/=]+)\$([a-zA-Z0-9+=/]+):([a-zA-Z0-9+/=]+)', '\1$\2:<salt>$<storedkey>:<serverkey>') as rolpassword_masked
     FROM pg_authid
@@ -64,7 +64,6 @@ DROP ROLE regress_passwd2;
 DROP ROLE regress_passwd3;
 DROP ROLE regress_passwd4;
 DROP ROLE regress_passwd5;
-DROP ROLE regress_passwd6;
 
 -- all entries should have been removed
 SELECT rolname, rolpassword