diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml
index c4b9971a20..2a859caac6 100644
--- a/doc/src/sgml/client-auth.sgml
+++ b/doc/src/sgml/client-auth.sgml
@@ -230,7 +230,10 @@ hostnogssenc  <replaceable>database</replaceable>  <replaceable>user</replaceabl
        virtue of being a superuser.
        The value <literal>replication</literal> specifies that the record
        matches if a physical replication connection is requested (note that
-       replication connections do not specify any particular database).
+       replication connections do not specify any particular database);
+       it does not match logical replication connections, which specify
+       <literal>replication=database</literal> and a <literal>dbname</literal>
+       in their connection string.
        Otherwise, this is the name of
        a specific <productname>PostgreSQL</productname> database.
        Multiple database names can be supplied by separating them with
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 545635f41a..c2f38702a5 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -382,6 +382,18 @@ ClientAuthentication(Port *port)
 					 errmsg("connection requires a valid client certificate")));
 	}
 
+	/*
+	 * The "replication" keyword in pg_hba.conf only applies to physical
+	 * replication connections and not logical replication connections,
+	 * so we'll just remind the user of that in case they've gotten confused.
+	 */
+#define PG_HBA_REPLICATION_RULE_DETAIL(am_walsender, am_db_walsender) \
+	(am_walsender ? \
+	  (am_db_walsender ? \
+	    errhint("Note logical replication connections do not match pg_hba.conf rules using the \"replication\" keyword") : \
+	    errhint("Note physical replication connections only match pg_hba.conf rules using the \"replication\" keyword")) : \
+	  0)
+
 	/*
 	 * Now proceed to do the actual authentication check
 	 */
@@ -417,21 +429,22 @@ ClientAuthentication(Port *port)
 #endif
 					_("no encryption");
 
-				if (am_walsender)
-					ereport(FATAL,
-							(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
-					/* translator: last %s describes encryption state */
-							 errmsg("pg_hba.conf rejects replication connection for host \"%s\", user \"%s\", %s",
-									hostinfo, port->user_name,
-									encryption_state)));
-				else
-					ereport(FATAL,
-							(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
-					/* translator: last %s describes encryption state */
-							 errmsg("pg_hba.conf rejects connection for host \"%s\", user \"%s\", database \"%s\", %s",
-									hostinfo, port->user_name,
-									port->database_name,
-									encryption_state)));
+#define REJECT_ERROR_MESSAGE(am_walsender, am_db_walsender, hostinfo, port, encryption_state) \
+				(am_walsender ? \
+				  (am_db_walsender ? \
+				    errmsg("pg_hba.conf rejects logical replication connection for host \"%s\", user \"%s\", database \"%s\", %s", \
+						   hostinfo, port->user_name, port->database_name, encryption_state) : \
+				    errmsg("pg_hba.conf rejects physical replication connection for host \"%s\", user \"%s\", %s", \
+						   hostinfo, port->user_name, encryption_state)) : \
+				  errmsg("pg_hba.conf rejects for host \"%s\", user \"%s\", database \"%s\", %s", \
+						 hostinfo, port->user_name, port->database_name, encryption_state))
+
+				ereport(FATAL,
+						(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
+						 /* translator: last %s describes encryption state */
+						 REJECT_ERROR_MESSAGE(am_walsender, am_db_walsender,
+											  hostinfo, port, encryption_state),
+						 PG_HBA_REPLICATION_RULE_DETAIL(am_walsender, am_db_walsender)));
 				break;
 			}
 
@@ -463,7 +476,17 @@ ClientAuthentication(Port *port)
 #endif
 					_("no encryption");
 
-#define HOSTNAME_LOOKUP_DETAIL(port) \
+#define IMPLICIT_REJECT_ERROR_MESSAGE(am_walsender, am_db_walsender, hostinfo, port, encryption_state) \
+				(am_walsender ? \
+				  (am_db_walsender ? \
+				    errmsg("no pg_hba.conf entry for logical replication connection from host \"%s\", user \"%s\", database \"%s\", %s" : \
+						   hostinfo, port->user_name, port->database_name, encryption_state) : \
+				    errmsg("no pg_hba.conf entry for physical replication connection from host \"%s\", user \"%s\", %s", \
+						   hostinfo, port->user_name, encryption_state)) : \
+				  errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s" \
+						 hostinfo, port->user_name, port->database_name, encryption_state))
+
+#define HOSTNAME_LOOKUP_DETAIL_LOG(port) \
 				(port->remote_hostname ? \
 				 (port->remote_hostname_resolv == +1 ? \
 				  errdetail_log("Client IP address resolved to \"%s\", forward lookup matches.", \
@@ -484,23 +507,13 @@ ClientAuthentication(Port *port)
 								  gai_strerror(port->remote_hostname_errcode)) : \
 					0))
 
-				if (am_walsender)
-					ereport(FATAL,
-							(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
-					/* translator: last %s describes encryption state */
-							 errmsg("no pg_hba.conf entry for replication connection from host \"%s\", user \"%s\", %s",
-									hostinfo, port->user_name,
-									encryption_state),
-							 HOSTNAME_LOOKUP_DETAIL(port)));
-				else
-					ereport(FATAL,
-							(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
-					/* translator: last %s describes encryption state */
-							 errmsg("no pg_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
-									hostinfo, port->user_name,
-									port->database_name,
-									encryption_state),
-							 HOSTNAME_LOOKUP_DETAIL(port)));
+				ereport(FATAL,
+						(errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
+						 /* translator: last %s describes encryption state */
+						 IMPLICIT_REJECT_ERROR_MESSAGE(am_walsender, am_db_walsender,
+													   hostinfo, port, encryption_state)
+						 HOSTNAME_LOOKUP_DETAIL_LOG(port),
+						 PG_HBA_REPLICATION_RULE_DETAIL(am_walsender, am_db_walsender));
 				break;
 			}
 
