ORA-04068: Midday Hotfix Broke 30% of Checkouts
ORA-04068 means a package your session already used was recompiled, so its state was thrown away.
20+ years shipping high-throughput database systems. Notes here come from systems that actually shipped.
- ✓Basic PL/SQL syntax (packages, procedures, functions)
- ✓Familiarity with Oracle SQL*Plus or SQL Developer
- ✓Understanding of database sessions and transactions
- ORA-04068: a package your session already used was recompiled, so Oracle discarded that session's package state. The next call reinitialises it and succeeds, so a single retry works.
- It does not roll back your transaction. Only the failing call errors; uncommitted work stays pending until your code commits or rolls back.
- Prevent it by deploying stateful packages in a maintenance window, recycling connection pools after deploys, moving state out of packages, or using Edition-Based Redefinition.
- ORA-04063: the object is INVALID. Run SHOW ERRORS (or query USER_ERRORS), fix the real error, which is often in a dependency, and recompile.
Imagine a cashier who keeps a running tally in their head. Mid-shift, management swaps the till software. The cashier's tally no longer matches the new system, so they shout "lost my count!" once, start a fresh tally and carry on. That shout is ORA-04068. ORA-04063 is when the new till software won't even boot: nobody can use it until it's fixed.
ORA-04068 looks like a random glitch: some sessions fail, others don't, and a retry works. It isn't random. It fires exactly once in every session that had already used a package before someone recompiled it. ORA-04063 is its louder sibling: the package didn't compile, so every caller fails until it does. This guide explains what package state is, why a deploy discards it, how to tell the two errors apart from the error stack, and the deployment patterns that keep both out of your incident channel.
Why Oracle Discards Package State (And Why It's Not a Bug)
A PL/SQL package can hold session state: variables, constants and cursors declared at package level, in the spec or the body. Each session gets its own private copy the first time it touches the package, and that copy lives until the session ends. When the package is recompiled, Oracle can't map the old state onto the new code, so it throws the state away. The next call from any session that already held state raises ORA-04068, and the stack usually adds ORA-04061, ORA-04065 or ORA-06508 underneath. Two details matter in production. First, it fires exactly once per affected session: the next call re-initialises the package and works. Second, it does not roll back your transaction. Only the failing call errors out; earlier uncommitted DML is still pending until your code commits or rolls back. Sessions that never touched the package, and packages with no package-level state at all, are unaffected. That's why it looks random.
ORA-04063: When Your Package Won't Even Compile
ORA-04063 means the object you called is INVALID: it has compilation errors, so Oracle refuses to run it. It names the object but not the line. It usually appears after a deployment in which something the package depends on changed: a column was renamed or dropped, a referenced package's spec changed, or a grant was revoked. Oracle marks the dependent package INVALID and tries to recompile it on the next call. If that compile fails, every caller gets ORA-04063. Unlike ORA-04068, retrying never helps. The fix is always: read the compile errors, fix the cause, recompile. Remember that the cause is often not in the package's own code, but in an object it depends on.
USER_ERRORS directly to get the full error text without SQL*Plus formatting: SELECT line, position, text FROM user_errors WHERE name = 'ORDER_PKG' AND type = 'PACKAGE BODY' ORDER BY sequence;The Deployment Pattern Behind Most ORA-04068
Almost every ORA-04068 incident has the same shape: a stateful package is recompiled while a connection pool is holding long-lived sessions that have already used it. Each of those sessions fails exactly once, spread over the next few minutes as the pool hands them out. Note that a recompile doesn't only come from your own deploy. Changing anything the package depends on, such as a table, a view or another package's spec, invalidates it, and Oracle recompiles it automatically on the next call. There are three reliable fixes. You can deploy in a window and recycle the pool, so no session carries old state. You can remove package-level state from hot packages, so there's nothing to discard. Or you can use Edition-Based Redefinition (EBR), where new code goes into a new edition: sessions already connected keep using the old edition, and new sessions pick up the new one. EBR is available in every Oracle edition, but it needs schema preparation: editions enabled for the owner, and editioning views over the tables.
How to Handle ORA-04068 in Application Code
You can't stop someone else's deploy from discarding state, but you can make the application shrug it off. Because ORA-04068 fires only once per session, a single retry of the same call on the same connection succeeds: that first failure is what re-initialises the package. Retry only on error code 4068, and only once. If the retry fails too, something else is wrong, such as ORA-04063, and you should surface it. Think about the transaction. The failed call didn't roll anything back, so retrying just that call inside the same transaction is safe. If your framework rolls back on any SQLException, retry the whole unit of work instead. The retry has one limit: after a retry the package state starts fresh. If your logic depended on values cached in package variables earlier in the session, they're gone, which is another reason to keep hot packages stateless.
Diagnosing ORA-04063: It's Not Always Your Package
When ORA-04063 names a package that you didn't touch, look at what it depends on. If any object it references changes or becomes invalid, the package is invalidated too, and the failure cascades up the dependency chain. Start with the errors of the named object in USER_ERRORS. They usually name the real culprit: a missing column, a changed function signature, or a missing grant. Then list INVALID objects and their dependencies. To recompile, don't write a loop of ALTER statements. Package bodies need ALTER PACKAGE ... COMPILE BODY, and getting the order right by hand is error-prone. Use UTL_RECOMP or DBMS_UTILITY.COMPILE_SCHEMA, which compile in dependency order. Be aware that recompiling stateful packages will itself cause ORA-04068 in live sessions, so do it in the same deploy window.
Make Hot Packages Stateless (and Where SERIALLY_REUSABLE Fits)
The most durable fix is to give ORA-04068 nothing to discard. A package with no package-level variables, constants or cursors has no session state, and recompiling it doesn't raise ORA-04068 in other sessions. Move cached values into a function that queries the source, into an application context (SYS_CONTEXT), or into a table. Pass anything else as parameters. PRAGMA SERIALLY_REUSABLE is the other option. It keeps package state only for the duration of one server call, so there's nothing long-lived to invalidate. The cost is that variables reset on every call, and serially reusable packages can't be called from SQL statements. Use it for genuinely call-scoped state, not as a blanket fix.
Midday Hotfix Broke 30% of Checkouts
- ORA-04068 isn't random: it hits every session that used the package before the recompile, exactly once.
- Remove package-level state from hot packages, or deploy them in a way that doesn't touch live sessions.
SELECT object_name, object_type, status, last_ddl_time FROM user_objects WHERE last_ddl_time > SYSDATE - 1/24 ORDER BY last_ddl_time DESC;SELECT referenced_name, referenced_type FROM user_dependencies WHERE name = 'ORDER_PKG';| File | Command / Code | Purpose |
|---|---|---|
| package_state_demo.sql | CREATE OR REPLACE PACKAGE order_pkg AS | Why Oracle Discards Package State (And Why It's Not a Bug) |
| ora04063_diagnose.sql | CREATE OR REPLACE PACKAGE BODY order_pkg AS | ORA-04063 |
| ebr_deploy.sql | ALTER USER app ENABLE EDITIONS; | The Deployment Pattern Behind Most ORA-04068 |
| OrderService.java | public class OrderService { | How to Handle ORA-04068 in Application Code |
| dependency_chain.sql | SELECT object_name, object_type, last_ddl_time | Diagnosing ORA-04063 |
| stateless_package.sql | CREATE OR REPLACE PACKAGE BODY tax_pkg AS | Make Hot Packages Stateless (and Where SERIALLY_REUSABLE Fit |
Key takeaways
Interview Questions on This Topic
How does Oracle handle package state when a package is recompiled, and why does it cause ORA-04068?
Frequently Asked Questions
20+ years shipping high-throughput database systems. Notes here come from systems that actually shipped.
That's PL/SQL. Mark it forged?
3 min read · try the examples if you haven't