- Error code
- ORA-20000
- Product
- Oracle Database
- Versions
- Oracle Database 19c, 21c, 23ai and 26ai (the text is written by the application)
- Category
- PL/SQL & Triggers
- Last reviewed
- 24 October 2026
On this page
What it means
ORA-20000 (and every code up to ORA-20999) is an error raised on purpose by PL/SQL code with RAISE_APPLICATION_ERROR; the message text was written by that code's author, so it describes an application rule, not an Oracle failure.
Oracle reserves the range -20000 to -20999 for application errors. A stored procedure, function, trigger or package calls RAISE_APPLICATION_ERROR(error_code, message) with a number in that range and a message of up to 2048 bytes, and the caller receives it like any other Oracle error. Oracle's reference says only that RAISE_APPLICATION_ERROR was called, and its action is to correct the problem the message describes, or ask the application administrator or DBA.
That means the meaning is in the text after the number, and the person who can explain it is whoever wrote that code. The ORA-06512 lines under it show which unit and line raised it. Oracle's own supplied packages use the range too: for example the DBMS_UTILITY documentation lists ORA-20000 for COMPILE_SCHEMA when there are "insufficient privileges for some object in this schema".
The optional third argument decides what happens to errors that were already on the stack: TRUE puts the new error on top of them, while the default FALSE replaces the stack with the new error. With FALSE, an error raised in an exception handler hides the original cause, so the stack shows only the application message.
Common causes
- A business rule in the application rejected the operation: a check in a procedure, package or trigger found invalid input or a disallowed state, and raised an error with a message for the user.
- A trigger enforces a rule that a constraint cannot express (for example no changes to dispatched orders) and refused the DML.
- An exception handler caught a lower-level error such as NO_DATA_FOUND and converted it into an application error with RAISE_APPLICATION_ERROR.
- An Oracle-supplied package (owned by SYS) raised an error in this range, as some document in their exception lists.
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.
Find the code that raises this number
SELECT owner, name, type, line, text
FROM all_source
WHERE UPPER(text) LIKE '%RAISE_APPLICATION_ERROR%'
AND text LIKE '%-20000%'
ORDER BY owner, name, line; Each RAISE_APPLICATION_ERROR call that uses -20000. Many applications reuse -20000 for everything, so also search for a fragment of the message text, and compare with the unit and line from the first ORA-06512 line.
Search by message text
SELECT owner, name, type, line, text
FROM all_source
WHERE owner = 'SHOP'
AND UPPER(text) LIKE UPPER('%cannot be cancelled%')
ORDER BY name, line; The line that builds the message. The surrounding IF tells you exactly which condition was true.
Is it your code or an Oracle-supplied package?
SELECT owner, object_name, object_type
FROM all_objects
WHERE object_name = 'CANCEL_ORDER' -- the unit named in the first ORA-06512 line
ORDER BY owner; An owner such as SYS means an Oracle-supplied package raised it: look the number up in that package's documentation. Any other owner is application code: ask its developers or read the source.
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.
Act on the message: it is the application's rule
Read-onlyRead the text after the number and the code that raised it. Usually the right fix is to change the input or the order of operations (for example cancel before dispatch), not the database. Changing or removing the check is a decision for the application's owners.
Catch a specific application error by name in the caller
Changes schemaGive the number a name with PRAGMA EXCEPTION_INIT and handle just that case, so other errors still propagate. Oracle's PL/SQL reference shows this pattern for RAISE_APPLICATION_ERROR.
CREATE OR REPLACE PROCEDURE shop.try_cancel (p_order_id IN NUMBER, p_result OUT VARCHAR2)
IS
already_dispatched EXCEPTION;
PRAGMA EXCEPTION_INIT (already_dispatched, -20000);
BEGIN
shop.cancel_order(p_order_id);
p_result := 'CANCELLED';
EXCEPTION
WHEN already_dispatched THEN
p_result := 'TOO_LATE'; -- SQLERRM holds the full message if you need it
END;
/
When you raise application errors, use distinct numbers and keep the stack
Changes schemaGive each condition its own number (and document them in one package), so callers can handle them separately. When converting another exception inside a handler, pass TRUE as the third argument so the original error stays on the stack under yours.
CREATE OR REPLACE PROCEDURE shop.cancel_order (p_order_id IN NUMBER)
IS
v_status shop.orders.status%TYPE;
BEGIN
SELECT status INTO v_status FROM shop.orders WHERE id = p_order_id;
IF v_status = 'DISPATCHED' THEN
RAISE_APPLICATION_ERROR(-20000,
'Order ' || p_order_id || ' cannot be cancelled: it has already been dispatched');
END IF;
UPDATE shop.orders SET status = 'CANCELLED' WHERE id = p_order_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RAISE_APPLICATION_ERROR(-20001, 'Order ' || p_order_id || ' does not exist', TRUE);
END;
/
Examples
An unhandled application error from a procedure
Not reproduced here: no Oracle Database is installed for this site. The procedure and message come from the RAISE_APPLICATION_ERROR example in Oracle's PL/SQL Language Reference; the ORA-06512 lines follow Oracle's documented stack layout, and the schema and line numbers are illustrative.
CREATE OR REPLACE PROCEDURE account_status (due_date DATE, today DATE) IS
BEGIN
IF due_date < today THEN
RAISE_APPLICATION_ERROR(-20000, 'Account past due.');
END IF;
END;
/
BEGIN
account_status(DATE '2026-07-01', DATE '2026-07-09');
END;
/
ORA-20000: Account past due. ORA-06512: at "SHOP.ACCOUNT_STATUS", line 4 ORA-06512: at line 2
Handling it by name with EXCEPTION_INIT
Not reproduced here: no Oracle Database is installed for this site. This is the documented example from Oracle's PL/SQL Language Reference, whose result is the line shown (printed by DBMS_OUTPUT, not raised as an error): the block handled the exception, so the caller sees no error.
DECLARE
past_due EXCEPTION;
PRAGMA EXCEPTION_INIT (past_due, -20000);
BEGIN
account_status(DATE '2026-07-01', DATE '2026-07-09');
EXCEPTION
WHEN past_due THEN
DBMS_OUTPUT.PUT_LINE(TO_CHAR(SQLERRM(-20000)));
END;
/
ORA-20000: Account past due.
How to prevent it
For application developers: keep a documented list of your -20xxx numbers and their meanings, write messages that say what was wrong and what to do, and include the key values (order id, customer id). Pass TRUE when converting another error so the cause is not lost.
For callers: handle the specific numbers you expect with EXCEPTION_INIT, show the message to the user where it is meant for them, and log the full stack for anything else.
Common questions
What does ORA-20000 mean?
It is not a built-in Oracle failure: some PL/SQL code called RAISE_APPLICATION_ERROR with that number and the message you see. Read the message, and use the ORA-06512 lines to find the code that raised it.
What is the difference between ORA-20000 and ORA-20001?
Only what the code that raised them chose. Any number from -20000 to -20999 can be used; applications usually give each kind of problem its own number so callers can tell them apart.
How long can the message be?
Oracle documents the RAISE_APPLICATION_ERROR message as a character string of at most 2048 bytes. Note that SQLERRM returns at most 512 bytes, so use DBMS_UTILITY.FORMAT_ERROR_STACK to log long messages in full.
Learn more on CodeWithSQL
Official documentation
- ORA-20000 (Oracle Database Error Messages)
- Raising exceptions explicitly, RAISE_APPLICATION_ERROR (Oracle PL/SQL Language Reference 19c)
- EXCEPTION_INIT pragma (Oracle PL/SQL Language Reference 19c)
- Retrieving error code and error message (Oracle PL/SQL Language Reference 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.