- Error code
- ORA-01031
- Product
- Oracle Database
- Versions
- Oracle Database 19c, 21c, 23ai and 26ai (same wording)
- Category
- Logins, Accounts & Privileges
- Last reviewed
- 24 October 2026
On this page
What it means
ORA-01031 means you tried an operation that needs a privilege your session does not have in that context, so Oracle refused it; the fix is to grant that one privilege, not a broad role.
Oracle's reference says only that a database operation was attempted without the required privileges, and the Action is to ask your administrator to grant them. The real work is finding which privilege, and why you do not have it where it is needed. There are two kinds: system privileges (CREATE TABLE, CREATE VIEW, CREATE SESSION, ALTER USER) and object privileges on a specific object (SELECT, INSERT, UPDATE, DELETE, EXECUTE). If you cannot see an object at all, Oracle usually reports ORA-00942 instead; ORA-01031 typically means you can see it but not do this to it.
Two Oracle rules explain most "but I have that privilege" cases. First, privileges that come through a role do not apply inside a definer's rights PL/SQL unit: the PL/SQL Language Reference says that while such a unit runs, only the role PUBLIC is enabled. Dynamic SQL in a procedure (EXECUTE IMMEDIATE 'CREATE TABLE ...') then fails with ORA-01031 even though the same statement works in your session. Second, CREATE VIEW requires the view owner's privileges on the underlying tables to be granted directly, not through a role.
Connecting AS SYSDBA is another frequent source. With operating system authentication, Oracle grants SYSDBA to members of the OSDBA group (commonly named dba on Linux and UNIX; ORA_DBA on Windows); with password file authentication, the user must be listed in the password file with SYSDBA. Without either, the connection fails with ORA-01031.
Common causes
- A missing system privilege, such as CREATE VIEW, CREATE SEQUENCE or CREATE PROCEDURE, for the statement you ran.
- You can query a table but have no UPDATE, INSERT or DELETE privilege on it.
- A definer's rights procedure uses dynamic SQL that relies on a privilege the owner has only through a role, such as CREATE TABLE from a role.
- CREATE VIEW over another schema's table when the owner's SELECT on it comes through a role, not a direct grant.
- Connecting AS SYSDBA from an operating system account that is not in the OSDBA group, or as a user who is not in the password file with SYSDBA.
- An administrative statement such as ALTER SYSTEM or CREATE USER run by an ordinary user.
Diagnose it
Read-only These queries only read the data dictionary (USER_, ALL_ and DBA_ views) and dynamic performance views (V$). They do not change data, privileges or settings, so they are safe to run first. DBA_ and V$ views need the matching privileges.
Which privileges and roles does my session have right now?
SELECT privilege FROM session_privs ORDER BY privilege;
SELECT role FROM session_roles ORDER BY role; The system privileges and roles active in your session. If the privilege the statement needs is missing from SESSION_PRIVS, that is the cause.
Is the privilege granted directly or only through a role?
Matters for stored procedures and views. USER_SYS_PRIVS and USER_TAB_PRIVS show direct grants; USER_ROLE_PRIVS shows roles.
-- direct system privileges
SELECT privilege, admin_option FROM user_sys_privs ORDER BY privilege;
-- direct object privileges on one table
SELECT owner, table_name, privilege, grantor
FROM user_tab_privs
WHERE owner = 'SHOP' AND table_name = 'ORDERS';
-- roles granted to you
SELECT granted_role, default_role FROM user_role_privs; If CREATE TABLE or SELECT on SHOP.ORDERS appears only through a role, it will not work inside a definer's rights procedure or a view owned by you.
Is the procedure definer's rights or invoker's rights?
SELECT owner, object_name, object_type, authid
FROM all_procedures
WHERE owner = 'SHOP'
AND object_name = 'MAKE_REPORT_TABLE'; AUTHID DEFINER: the unit runs with the owner's directly granted privileges and PUBLIC only. CURRENT_USER: it runs with the caller's privileges and enabled roles.
Who may connect AS SYSDBA through the password file?
Needs SELECT on V$ views. For operating system authentication, check instead that your OS account is in the OSDBA group on the database server.
SELECT username, sysdba, sysoper, sysbackup, sysdg, syskm
FROM v$pwfile_users; Users that can connect with administrative privileges using a password. A user not listed with SYSDBA TRUE cannot connect AS SYSDBA by password.
How to fix it
Each fix is labelled with what it changes. Try read-only checks and the least invasive fix first, and test changes outside production.
Grant the one privilege that is missing
Changes permissionsAn administrator grants exactly what the statement needs, to the user or to a role the user has. Prefer object privileges on specific objects over ANY system privileges (such as SELECT ANY TABLE), which apply to every schema.
GRANT CREATE VIEW TO report_user;
GRANT SELECT, UPDATE ON shop.orders TO order_app;
Grant directly for stored code and views
Changes permissionsFor a definer's rights procedure or a view, the owner needs the privilege granted directly. Alternatives Oracle documents: make the unit invoker's rights (AUTHID CURRENT_USER) so it uses the caller's privileges, or grant a role to the PL/SQL unit itself. Oracle says roles are typically granted to invoker's rights units, and to a definer's rights unit only when it issues dynamic SQL, as here.
-- direct grant to the procedure owner
GRANT CREATE TABLE TO shop;
-- or grant a role to the unit (code based access control)
GRANT report_maker_role TO PROCEDURE shop.make_report_table;
Connect AS SYSDBA the supported way
Changes configurationAsk the system administrator to add your operating system account to the OSDBA group of that Oracle home (dba on Linux and UNIX, ORA_DBA on Windows), or connect as a user that is in the password file with SYSDBA. Use SYSDBA only for administration; everyday work belongs in an ordinary account.
Do not grant DBA to make the error go away
Read-onlyNever grant the DBA role, ALL PRIVILEGES or ANY privileges to an application or user just to stop ORA-01031. They give far more than the one operation needed, across every schema, and are hard to take back once code depends on them. Find the specific privilege with the queries above and grant only that.
Examples
Dynamic SQL in a procedure that relies on a role
Not reproduced here: no Oracle Database is installed for this site. The message format is from Oracle's error reference, and the behaviour follows the PL/SQL Language Reference (only PUBLIC is enabled while a definer's rights unit runs). The ORA-06512 lines and line numbers are illustrative. The same CREATE TABLE typed directly in SHOP's session would succeed, because the role is enabled there.
-- SHOP has CREATE TABLE only through a role
CREATE OR REPLACE PROCEDURE make_report_table AS
BEGIN
EXECUTE IMMEDIATE 'CREATE TABLE report_2026 (id NUMBER)';
END;
/
EXEC make_report_table
ORA-01031: insufficient privileges ORA-06512: at "SHOP.MAKE_REPORT_TABLE", line 3 ORA-06512: at line 1
Updating a table you can only query
Not reproduced here: no Oracle Database is installed for this site. The message format is from Oracle's error reference; the user, table and line are illustrative.
-- REPORT_USER has SELECT on SHOP.ORDERS, nothing else
UPDATE shop.orders SET status = 'CANCELLED' WHERE id = 42;
ERROR at line 1: ORA-01031: insufficient privileges
Connecting AS SYSDBA from an account outside the OSDBA group
Not reproduced here: no Oracle Database is installed for this site. The message format is from Oracle's error reference; the OSDBA group rules are from Oracle's Administrator's Guide.
sqlplus / as sysdba
ERROR: ORA-01031: insufficient privileges
How to prevent it
Give each application its own user or role with a written list of the privileges it needs, and grant object privileges on named objects rather than ANY privileges or DBA. Grant directly to schema owners whatever their stored code and views depend on.
When you write a definer's rights procedure, test it from a session where the owner's roles are not enabled, and use SESSION_PRIVS and USER_SYS_PRIVS to check what really applies.
Common questions
Why does my statement work in SQL*Plus but fail with ORA-01031 in a procedure?
Inside a definer's rights procedure, only privileges granted directly to the owner (and to PUBLIC) apply; roles are not enabled. Grant the privilege directly to the owner, make the procedure AUTHID CURRENT_USER, or grant a role to the procedure itself.
Why do I get ORA-01031 with sqlplus / as sysdba?
Operating system authentication gives SYSDBA only to members of the OSDBA group (dba on Linux and UNIX, ORA_DBA on Windows). Add your OS account to that group, or connect as a user in the password file that has SYSDBA.
Is granting the DBA role a good fix?
No. It grants almost every privilege in the database to fix one missing privilege. Find the specific system or object privilege the statement needs and grant only that.
Learn more on CodeWithSQL
Official documentation
- ORA-01031 (Oracle Database Error Messages)
- Invoker's Rights and Definer's Rights (Oracle PL/SQL Language Reference 19c)
- GRANT (Oracle SQL Language Reference 19c)
- Getting Started with Database Administration (Oracle Database Administrator's Guide 19c)
Last technically reviewed 24 October 2026; examples and diagnostics run on Oracle Database Error Messages reference (26ai, 21c and 19c); not run locally. Messages and explanations follow Oracle's Database Error Messages reference; no Oracle Database was available, so the examples were not run locally.