DEV Community

umzzil nng
umzzil nng

Posted on Originally published at oraerror.com

Oracle ORA-04061 Error: Causes and Solutions Complete Guide

ORA-04061: Existing State Has Been Invalidated — What You Need to Know

ORA-04061 is a common Oracle error that occurs when a PL/SQL object (package, procedure, function, or trigger) that a session has already loaded into memory becomes invalidated due to a DDL change on that object or one of its dependencies. Oracle detects that the state held by the current session no longer matches the current definition of the object and raises this error to protect data integrity. In most cases, simply retrying the call or reconnecting the session resolves the issue, as Oracle will recompile the object automatically on the next invocation.


Top 3 Causes

1. Package or Stored Object Recompiled During Active Session

The most frequent cause is a developer or DBA recompiling a package body or replacing a stored procedure while other sessions are actively using it. When the DDL executes, all sessions that have the old version of the package loaded in their UGA (User Global Area) will receive ORA-04061 on their next call.

-- This DDL invalidates the package for all active sessions using it
CREATE OR REPLACE PACKAGE BODY my_package AS
  FUNCTION get_data(p_id IN NUMBER) RETURN VARCHAR2 IS
  BEGIN
    RETURN 'Updated Result for ID: ' || p_id;
  END get_data;
END my_package;
/

-- Recompile explicitly after changes
ALTER PACKAGE my_package COMPILE;
ALTER PACKAGE my_package COMPILE BODY;

-- Check for INVALID objects after deployment
SELECT object_name, object_type, status, last_ddl_time
FROM   dba_objects
WHERE  status = 'INVALID'
  AND  owner  = 'MY_SCHEMA'
ORDER  BY last_ddl_time DESC;
Enter fullscreen mode Exit fullscreen mode

2. DDL Changes on Referenced Tables or Views

If a package references a table and that table's structure changes (e.g., a column is added or dropped), Oracle automatically marks the dependent PL/SQL objects as INVALID. Any session that tries to use those objects before they are recompiled will encounter ORA-04061.

-- Adding a column invalidates dependent packages
ALTER TABLE employee ADD (department_code VARCHAR2(10));

-- Check which objects depend on the changed table
SELECT d.name        AS dependent_object,
       d.type        AS object_type,
       o.status
FROM   dba_dependencies d
JOIN   dba_objects      o
       ON  o.object_name = d.name
       AND o.owner       = d.owner
WHERE  d.referenced_name = 'EMPLOYEE'
  AND  d.type IN ('PACKAGE', 'PACKAGE BODY', 'PROCEDURE', 'FUNCTION')
  AND  d.owner = 'MY_SCHEMA';

-- Recompile all INVALID objects in the schema
EXEC UTL_RECOMP.RECOMP_SERIAL('MY_SCHEMA');
Enter fullscreen mode Exit fullscreen mode

3. Stateful Package Variable Invalidation

Packages that maintain state (global variables, cursors, constants) are especially vulnerable. When the package is recompiled, all session-level package state is discarded. Oracle raises ORA-04061 (often followed by ORA-04065 and ORA-04068) to signal that the previously held state is gone and the session must reinitialize.

-- Example of a stateful package (vulnerable to ORA-04061)
CREATE OR REPLACE PACKAGE session_state_pkg AS
  g_user_id   NUMBER;
  g_user_name VARCHAR2(100);
  PROCEDURE initialize(p_id IN NUMBER);
END session_state_pkg;
/

-- Safe error handling pattern in application code
CREATE OR REPLACE PROCEDURE call_with_retry AS
  v_result VARCHAR2(200);
BEGIN
  v_result := my_package.get_data(p_id => 1);
EXCEPTION
  WHEN OTHERS THEN
    -- Catch ORA-04061, ORA-04065, ORA-04068
    IF SQLCODE IN (-4061, -4065, -4068) THEN
      -- Re-initialize and retry once
      v_result := my_package.get_data(p_id => 1);
    ELSE
      RAISE;
    END IF;
END call_with_retry;
/
Enter fullscreen mode Exit fullscreen mode

Quick Fix Solutions

-- 1. Recompile a specific object
ALTER PACKAGE my_package COMPILE BODY;
ALTER PROCEDURE my_procedure COMPILE;

-- 2. Recompile all INVALID objects in a schema (parallel mode)
EXEC UTL_RECOMP.RECOMP_PARALLEL(4, 'MY_SCHEMA');

-- 3. Full database recompile (run as SYS during maintenance)
@$ORACLE_HOME/rdbms/admin/utlrp.sql

-- 4. Verify all objects are VALID after recompile
SELECT COUNT(*) AS still_invalid
FROM   dba_objects
WHERE  status = 'INVALID'
  AND  owner  = 'MY_SCHEMA';
Enter fullscreen mode Exit fullscreen mode

Prevention Tips

Deploy during a maintenance window. Always perform DDL changes (package replacements, table alterations) during scheduled downtime. After deployment, run UTL_RECOMP or utlrp.sql and verify zero INVALID objects before reopening connections. If using a connection pool, force a full pool flush so old sessions with stale package state are discarded.

Analyze dependencies before deploying. Use DBA_DEPENDENCIES to map out all objects affected by your change. Deploy from the lowest-level dependency upward (referenced objects first, dependent objects last) to minimize cascading invalidations. Automating this check as part of your CI/CD pipeline prevents surprises in production.


Related Errors

Error Code Description
ORA-04062 Timestamp of the package/procedure has changed
ORA-04065 Stored procedure altered or dropped, not executed
ORA-04068 Existing state of packages has been discarded
ORA-06508 Could not find program unit being called

These errors almost always appear together in a stack. If you see ORA-04061, check for ORA-04068 immediately — it confirms the package state was fully discarded and the session must reinitialize before the next successful call.


📖 Want a more detailed guide?
Check out the full in-depth version (Korean) on oraerror.com — includes detailed analysis, additional SQL examples, and prevention tips.

Top comments (0)