diff --git a/doc/src/sgml/logical-replication.sgml b/doc/src/sgml/logical-replication.sgml
index 5befefd9c5a..d7d75b7c9a5 100644
--- a/doc/src/sgml/logical-replication.sgml
+++ b/doc/src/sgml/logical-replication.sgml
@@ -2542,9 +2542,10 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER
- In order to be able to copy the initial table or sequence data, the role
- used for the replication connection must have the SELECT
- privilege on a published table or sequence (or be a superuser).
+ In order to be able to copy the initial table data or synchronize
+ sequences, the role used for the replication connection must have the
+ SELECT privilege on a published table or sequence (or be
+ a superuser).
@@ -2611,6 +2612,13 @@ CONTEXT: processing remote data for replication origin "pg_16395" during "INSER
security within the database is of no concern.
+
+ When synchronizing sequences with
+ run_as_owner = true, the subscription owner similarly
+ needs UPDATE privilege on the target sequence and does
+ not need privileges to SET ROLE to the sequence owner.
+
+
On the publisher, privileges are only checked once at the start of a
replication connection and are not re-checked as each change record is read.
diff --git a/src/backend/replication/logical/sequencesync.c b/src/backend/replication/logical/sequencesync.c
index f47f962c7db..770fa5de10b 100644
--- a/src/backend/replication/logical/sequencesync.c
+++ b/src/backend/replication/logical/sequencesync.c
@@ -201,12 +201,26 @@ report_sequence_errors(List *mismatched_seqs_idx,
if (sub_insuffperm_seqs_idx)
{
get_sequences_string(sub_insuffperm_seqs_idx, &seqstr);
+
+ /*
+ * With run_as_owner enabled, sequence synchronization runs as the
+ * subscription owner, so a missing UPDATE privilege should be granted
+ * to that role. Otherwise, the worker switches to the sequence owner
+ * before checking privileges, so no useful GRANT hint can be
+ * provided.
+ */
ereport(WARNING,
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg_plural("insufficient privileges on subscriber sequence (%s)",
"insufficient privileges on subscriber sequences (%s)",
list_length(sub_insuffperm_seqs_idx),
- seqstr.data));
+ seqstr.data),
+ MySubscription->runasowner ?
+ errhint_plural("Grant UPDATE on the sequence to the subscription "
+ "owner on the subscriber.",
+ "Grant UPDATE on the sequences to the subscription "
+ "owner on the subscriber.",
+ list_length(sub_insuffperm_seqs_idx)) : 0);
}
if (pub_insuffperm_seqs_idx)
@@ -217,7 +231,12 @@ report_sequence_errors(List *mismatched_seqs_idx,
errmsg_plural("insufficient privileges on publisher sequence (%s)",
"insufficient privileges on publisher sequences (%s)",
list_length(pub_insuffperm_seqs_idx),
- seqstr.data));
+ seqstr.data),
+ errhint_plural("Grant SELECT on the sequence to the role used for "
+ "the replication connection on the publisher.",
+ "Grant SELECT on the sequences to the role used for "
+ "the replication connection on the publisher.",
+ list_length(pub_insuffperm_seqs_idx)));
}
if (missing_seqs_idx)