Cannot drop PostgreSQL role. Error: `cannot be dropped because some objects depend on it`
Asked Answered
B

6

132

I was trying to delete PostgreSQL user:

DROP USER ryan;

I received this error:

Error in query:
ERROR: role "ryan" cannot be dropped because some objects depend on it
DETAIL: privileges for database mydatabase

I looked for a solution from these threads:

Still have the same error.

This happens after I grant all permission to user "ryan" with:

GRANT ALL PRIVILEGES ON DATABASE mydatabase ON SCHEMA public TO ryan;
Babbette answered 10/7, 2018 at 2:28 Comment(0)
C
206

DROP USER (or DROP ROLE, same thing) cannot proceed while the role still owns anything or has any granted privileges on other objects.

Get rid of all privileges with DROP OWNED (which isn't too obvious from the wording). The manual:

[...] Any privileges granted to the given roles on objects in the current database and on shared objects (databases, tablespaces) will also be revoked.

So the reliable sequence of commands to drop a role is:

REASSIGN OWNED BY ryan TO postgres;  -- or some other trusted role
DROP OWNED BY ryan;

Run both commands in every database of the same cluster where the role owns anything or has any privileges!
And finally:

DROP USER ryan;
  • REASSIGN OWNED changes ownership for all objects currently owned by the role.
  • DROP OWNED then only revokes privileges (ownerships out of the way).

Alternatively, you can skip REASSIGN OWNED. Then DROP OWNED will (also) drop all objects owned by the user. (Are you sure?!)

Related:

Covetous answered 10/7, 2018 at 4:37 Comment(12)
I get this error even when the user doesn't own anything. It merely has GRANT permission on a few tables owned by another user. Therefore this solution won't work because there's nothing to reassign.Iridotomy
@Cerin: Did you to see the quoted sentence about DROP OWNED?Covetous
Thank you, one question though -- why you started with REASSIGN?Cleancut
@astrowalker: I added more explanation above.Covetous
I get "[42501] ERROR: permission denied to reassign objects" error thought use admin account to execute query.Cressler
@Tomas: Is the "admin account" actually a superuser? (SHOW IS_SUPERUSER; while connected as the role.)Covetous
@ErwinBrandstetter, thanks! Could you take this comment -- repeat both in ALL databases where the role owns anything or has any privileges! out of code block so it would appear more like instruction, not comment about the command? I spent few minutes wondering&experimenting before i noticed it ;)Chainman
@atsu85: I clarified a bit.Covetous
Neither reassigning OWNED nor dropping them worked for me. Still got the same error when running from a superuser.Hightoned
@rovyko: It's not "either / or", it's REASSIGN OWNED ... and DROP OWNED ... in every involved database of the same cluster before you can reliably DROP ROLE ...Covetous
For those of you who stumble onto this answer when working with Google Cloud SQL, note that it is not currently possible for REASSIGN OWNER to work. See https://mcmap.net/q/76993/-gcp-sql-postgres-problem-with-privileges-can-39-t-run-a-query-with-postgres-user-with-generated-symfony-db and cloud.google.com/sql/docs/postgres/users#superuser_restrictionsSpenser
This doesn't work with PostgreSQL on RDS, even from the master login.Iridotomy
P
37

What worked for me was to follow these steps:

  1. Connecting to the database
\c mydatabase
  1. Reassigning ownership
REASSIGN OWNED BY ryan TO <newuser>;

Or/and just deleting the object

DROP OWNED BY ryan;
  1. Executing REVOKE PRIVILEGES
REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM ryan;
REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public FROM ryan;
REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public FROM ryan;
  1. Dropping the user
DROP USER ryan;

PS: You might not need to execute both Step 2 and 3, just one of the two steps might be usually enough.

Pacification answered 5/2, 2019 at 4:42 Comment(3)
Use REVOKE CONNECT ON DATABASE db_name FROM role_name; and REVOKE ALL ON SCHEMA public FROM role_name; to revoke connect and usage privileges respectively. SourceIrish
Above comment works!Uncomfortable
I get: mydatabase=> REASSIGN OWNED BY ryan TO rian; ERROR: permission denied to reassign objectsCoppage
S
11

What worked for me on RDS Postgres 13:

REVOKE ALL PRIVILEGES ON DATABASE <my_db> FROM <my_user>;

I also had a similar error where the role was owner for tables so it couldn't be dropped, had to re-assign table owner with:

ALTER TABLE <my_table> OWNER TO <trusted_role>;

Doing a REASSIGN like this didn't work for me on RDS because AWS doesn't give you full superuser to your master user: REASSIGN OWNED BY <olduser> TO <newuser>;

Soulless answered 16/9, 2021 at 19:48 Comment(1)
I had an issue exactly with this stack. My solution is here: dba.stackexchange.com/a/301785/224108Cryobiology
M
9
REVOKE ALL ON SCHEMA "public" FROM "<user>";

Worked for me.

Maurer answered 19/7, 2022 at 19:23 Comment(3)
IMHO this is just a part of Andrews answer.Simulation
@Simulation REVOKE ALL PRIVILEGES ON DATABASE is not the same as REVOKE ALL ON SCHEMAMaurer
I'm aware of that, nevertheless the effect would be the same. It also occurs in Samuel Anyaeles answer the way you do it, yours is only a shorter form.Simulation
P
0

What worked for me was to recreate template1 database and then drop some role:

$ psql -U postgres postgres
postgres=# update pg_database set datistemplate = false where datname='template1';
UPDATE 1
postgres=# drop database template1;
DROP DATABASE
postgres=# create database template1 template=template0;
CREATE DATABASE
postgres=# update pg_database set datistemplate = true where datname='template1';
UPDATE 1
postgres=# DROP ROLE test;
DROP ROLE
Postmillennialism answered 26/8, 2020 at 8:30 Comment(0)
L
0

For people who use AWS Postgresql RDS, you may try following

  1. login to postgres user, then grant owner
postgres=> GRANT target_user to old_user;
GRANT ROLE
  1. Login to target db using user that would like to remove(old_user), then reassign
target_db=> REASSIGN OWNED BY old_user TO target_user;
REASSIGN OWNED
  1. Login back to postgres user, revoke all privileges then drop user
postgres=> REVOKE ALL PRIVILEGES ON DATABASE target_db FROM old_user;
REVOKE
postgres=> DROP USER old_user;
DROP ROLE

Ref. https://aws.amazon.com/premiumsupport/knowledge-center/rds-postgresql-drop-user-role/

Lazo answered 12/10, 2022 at 7:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.