diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 293b84bbca..8f80e5d8c0 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -91,7 +91,8 @@ static void vac_truncate_clog(TransactionId frozenXID,
 							  MultiXactId minMulti,
 							  TransactionId lastSaneFrozenXid,
 							  MultiXactId lastSaneMinMulti);
-static bool vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params);
+static bool vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params,
+					   bool skip_privs);
 static double compute_parallel_delay(void);
 static VacOptValue get_vacoptval_from_boolean(DefElem *def);
 static bool vac_tid_reaped(ItemPointer itemptr, void *state);
@@ -470,7 +471,7 @@ vacuum(List *relations, VacuumParams *params,
 
 			if (params->options & VACOPT_VACUUM)
 			{
-				if (!vacuum_rel(vrel->oid, vrel->relation, params))
+				if (!vacuum_rel(vrel->oid, vrel->relation, params, false))
 					continue;
 			}
 
@@ -1806,7 +1807,7 @@ vac_truncate_clog(TransactionId frozenXID,
  *		At entry and exit, we are not inside a transaction.
  */
 static bool
-vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params)
+vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, bool skip_privs)
 {
 	LOCKMODE	lmode;
 	Relation	rel;
@@ -1893,7 +1894,8 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params)
 	 * happen across multiple transactions where privileges could have changed
 	 * in-between.  Make sure to only generate logs for VACUUM in this case.
 	 */
-	if (!vacuum_is_permitted_for_relation(RelationGetRelid(rel),
+	if (!skip_privs &&
+		!vacuum_is_permitted_for_relation(RelationGetRelid(rel),
 										  rel->rd_rel,
 										  params->options & VACOPT_VACUUM))
 	{
@@ -2067,7 +2069,7 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params)
 	 * totally unimportant for toast relations.
 	 */
 	if (toast_relid != InvalidOid)
-		vacuum_rel(toast_relid, NULL, params);
+		vacuum_rel(toast_relid, NULL, params, true);
 
 	/*
 	 * Now release the session-level lock on the main table.
diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out
index 34c26a804a..5335e45434 100644
--- a/src/test/regress/expected/privileges.out
+++ b/src/test/regress/expected/privileges.out
@@ -2901,6 +2901,7 @@ CREATE INDEX ON maintain_test (a);
 GRANT MAINTAIN ON maintain_test TO regress_maintain;
 CREATE MATERIALIZED VIEW refresh_test AS SELECT 1;
 GRANT MAINTAIN ON refresh_test TO regress_maintain;
+GRANT MAINTAIN ON pg_type TO regress_maintain;
 CREATE SCHEMA reindex_test;
 -- negative tests; should fail
 SET ROLE regress_no_maintain;
@@ -2910,6 +2911,8 @@ ANALYZE maintain_test;
 WARNING:  permission denied to analyze "maintain_test", skipping it
 VACUUM (ANALYZE) maintain_test;
 WARNING:  permission denied to vacuum "maintain_test", skipping it
+VACUUM pg_type;
+WARNING:  permission denied to vacuum "pg_type", skipping it
 CLUSTER maintain_test USING maintain_test_a_idx;
 ERROR:  must be owner of table maintain_test
 REFRESH MATERIALIZED VIEW refresh_test;
@@ -2933,6 +2936,7 @@ SET ROLE regress_maintain;
 VACUUM maintain_test;
 ANALYZE maintain_test;
 VACUUM (ANALYZE) maintain_test;
+VACUUM pg_type;
 CLUSTER maintain_test USING maintain_test_a_idx;
 REFRESH MATERIALIZED VIEW refresh_test;
 REINDEX TABLE maintain_test;
@@ -2950,6 +2954,7 @@ SET ROLE regress_maintain_all;
 VACUUM maintain_test;
 ANALYZE maintain_test;
 VACUUM (ANALYZE) maintain_test;
+VACUUM pg_type;
 CLUSTER maintain_test USING maintain_test_a_idx;
 REFRESH MATERIALIZED VIEW refresh_test;
 REINDEX TABLE maintain_test;
@@ -2965,6 +2970,7 @@ RESET ROLE;
 DROP TABLE maintain_test;
 DROP MATERIALIZED VIEW refresh_test;
 DROP SCHEMA reindex_test;
+REVOKE MAINTAIN ON pg_type FROM regress_maintain;
 DROP ROLE regress_no_maintain;
 DROP ROLE regress_maintain;
 DROP ROLE regress_maintain_all;
diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql
index 39aa0b4ecf..5f36026eaa 100644
--- a/src/test/regress/sql/privileges.sql
+++ b/src/test/regress/sql/privileges.sql
@@ -1872,6 +1872,7 @@ CREATE INDEX ON maintain_test (a);
 GRANT MAINTAIN ON maintain_test TO regress_maintain;
 CREATE MATERIALIZED VIEW refresh_test AS SELECT 1;
 GRANT MAINTAIN ON refresh_test TO regress_maintain;
+GRANT MAINTAIN ON pg_type TO regress_maintain;
 CREATE SCHEMA reindex_test;
 
 -- negative tests; should fail
@@ -1879,6 +1880,7 @@ SET ROLE regress_no_maintain;
 VACUUM maintain_test;
 ANALYZE maintain_test;
 VACUUM (ANALYZE) maintain_test;
+VACUUM pg_type;
 CLUSTER maintain_test USING maintain_test_a_idx;
 REFRESH MATERIALIZED VIEW refresh_test;
 REINDEX TABLE maintain_test;
@@ -1896,6 +1898,7 @@ SET ROLE regress_maintain;
 VACUUM maintain_test;
 ANALYZE maintain_test;
 VACUUM (ANALYZE) maintain_test;
+VACUUM pg_type;
 CLUSTER maintain_test USING maintain_test_a_idx;
 REFRESH MATERIALIZED VIEW refresh_test;
 REINDEX TABLE maintain_test;
@@ -1913,6 +1916,7 @@ SET ROLE regress_maintain_all;
 VACUUM maintain_test;
 ANALYZE maintain_test;
 VACUUM (ANALYZE) maintain_test;
+VACUUM pg_type;
 CLUSTER maintain_test USING maintain_test_a_idx;
 REFRESH MATERIALIZED VIEW refresh_test;
 REINDEX TABLE maintain_test;
@@ -1929,6 +1933,7 @@ RESET ROLE;
 DROP TABLE maintain_test;
 DROP MATERIALIZED VIEW refresh_test;
 DROP SCHEMA reindex_test;
+REVOKE MAINTAIN ON pg_type FROM regress_maintain;
 DROP ROLE regress_no_maintain;
 DROP ROLE regress_maintain;
 DROP ROLE regress_maintain_all;
