ORA-01012: Not Logged On - Fix Oracle Session Errors
ORA-01012: Not Logged On
Section titled “ORA-01012: Not Logged On”Error Overview
Section titled “Error Overview”Error Text: ORA-01012: not logged on
The ORA-01012 error occurs when an application attempts to execute a database operation against a session that is no longer connected to Oracle. The session has been terminated — either by a DBA, a network interruption, an idle timeout policy, or an abnormal process exit — and the client-side connection handle is now invalid. Any subsequent call through that handle raises ORA-01012.
This error is most commonly seen in connection pools where a pooled connection has silently gone stale, and the pool hands it to an application thread without first validating it.
Common Causes
Section titled “Common Causes”1. Session Killed by a DBA
Section titled “1. Session Killed by a DBA”A DBA issued ALTER SYSTEM KILL SESSION or ALTER SYSTEM DISCONNECT SESSION targeting the session. The server-side session is marked killed immediately; any in-flight or subsequent client call receives ORA-01012.
2. Network Interruption
Section titled “2. Network Interruption”A firewall, load balancer, or network device silently dropped the TCP connection. Oracle’s server process may still exist in a SNIPED or killed state while the client-side driver holds a dangling socket.
3. Idle Timeout via SQLNET.EXPIRE_TIME / Dead Connection Detection
Section titled “3. Idle Timeout via SQLNET.EXPIRE_TIME / Dead Connection Detection”When SQLNET.EXPIRE_TIME is configured in sqlnet.ora, Oracle sends periodic probe packets. If the client is unreachable the session is terminated. Similarly, profiles with IDLE_TIME limits disconnect idle sessions.
4. Application Connection Pool Stale Connections
Section titled “4. Application Connection Pool Stale Connections”J2EE / JDBC connection pools, ODP.NET pools, and similar middleware cache connections. If the pool does not validate connections on borrow, a recycled connection that was killed server-side will fail on first use with ORA-01012.
5. Process or OS-Level Termination
Section titled “5. Process or OS-Level Termination”The Oracle server process (shadow process) was killed at the OS level (kill -9), or the database instance was bounced while the client still held the connection handle.
6. Profile-Based Resource Limits
Section titled “6. Profile-Based Resource Limits”A user profile with SESSIONS_PER_USER, CONNECT_TIME, or IDLE_TIME limits can force disconnection when limits are breached.
Diagnostic Queries
Section titled “Diagnostic Queries”Check for Recently Killed Sessions
Section titled “Check for Recently Killed Sessions”-- Sessions in KILLED or SNIPED stateSELECT sid, serial#, username, status, osuser, machine, last_call_et, programFROM v$sessionWHERE status IN ('KILLED', 'SNIPED')ORDER BY last_call_et DESC;Check Active Profile Limits
Section titled “Check Active Profile Limits”-- Review resource limits for a userSELECT username, profile FROM dba_users WHERE username = UPPER('&username');
SELECT resource_name, limitFROM dba_profilesWHERE profile = (SELECT profile FROM dba_users WHERE username = UPPER('&username')) AND resource_type = 'KERNEL';Check sqlnet.ora Timeout Parameters
Section titled “Check sqlnet.ora Timeout Parameters”-- View network-level parameters from the instance perspectiveSELECT name, valueFROM v$parameterWHERE name IN ('sqlnet.expire_time', 'tcp.connect_timeout', 'inbound_connect_timeout');
-- Check profile-based idle timeSELECT p.profile, p.resource_name, p.limitFROM dba_profiles pWHERE p.resource_name IN ('IDLE_TIME', 'CONNECT_TIME', 'SESSIONS_PER_USER')ORDER BY p.profile, p.resource_name;Identify the Killing Session from Audit Trail
Section titled “Identify the Killing Session from Audit Trail”-- Audit trail for session disconnects (if auditing enabled)SELECT db_user, os_user, userhost, action_name, TO_CHAR(timestamp, 'YYYY-MM-DD HH24:MI:SS') AS event_time, obj_name, comment$textFROM dba_audit_trailWHERE action_name IN ('LOGOFF BY CLEANUP', 'SESSION REC') AND timestamp > SYSDATE - 1ORDER BY timestamp DESC;Check Alert Log for Recent Kills
Section titled “Check Alert Log for Recent Kills”-- Use external table or ADRCI to scan alert log-- Quick view via V$DIAG_ALERT_EXT (12c+)SELECT originating_timestamp, message_textFROM v$diag_alert_extWHERE message_text LIKE '%killed%' OR message_text LIKE '%ORA-01012%'ORDER BY originating_timestamp DESCFETCH FIRST 20 ROWS ONLY;Validate Dead Connection Detection Settings
Section titled “Validate Dead Connection Detection Settings”-- Check if Dead Connection Detection is configured-- sqlnet.ora on the server should contain SQLNET.EXPIRE_TIME=10 (minutes)-- View OS-level file if accessible:-- $ORACLE_HOME/network/admin/sqlnet.ora
SELECT name, valueFROM v$parameterWHERE LOWER(name) LIKE '%expire%' OR LOWER(name) LIKE '%dead%';Step-by-Step Resolution
Section titled “Step-by-Step Resolution”1. Immediate Recovery — Application Side
Section titled “1. Immediate Recovery — Application Side”If your application receives ORA-01012, the connection must be discarded and a new one obtained:
// Java / JDBC example — discard and reconnecttry { stmt.executeQuery(sql);} catch (SQLException e) { if (e.getErrorCode() == 1012) { connection.close(); // discard the stale connection connection = dataSource.getConnection(); // obtain a fresh one stmt = connection.prepareStatement(sql); stmt.executeQuery(sql); // retry }}2. Enable Connection Validation in the Pool
Section titled “2. Enable Connection Validation in the Pool”For JDBC Universal Connection Pool (UCP):
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource();pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");pds.setURL("jdbc:oracle:thin:@//host:1521/service");// Validate connection before handing to applicationpds.setValidateConnectionOnBorrow(true);pds.setSQLForValidateConnection("SELECT 1 FROM DUAL");For Oracle JDBC connection pool (ojdbc):
# In datasource configurationoracle.jdbc.pool.OracleConnectionPoolDataSource.validateOnBorrow=trueoracle.jdbc.pool.OracleConnectionPoolDataSource.connectionValidationSQL=SELECT 1 FROM DUAL3. Check and Restore the Session (DBA Action)
Section titled “3. Check and Restore the Session (DBA Action)”-- Confirm whether session is truly goneSELECT sid, serial#, status, username, last_call_etFROM v$sessionWHERE username = UPPER('&username')ORDER BY last_call_et;
-- If a KILLED session is blocking resources, force cleanupALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
-- If the shadow process is still OS-resident (hung kill), find the OS PIDSELECT spid FROM v$processWHERE addr = (SELECT paddr FROM v$session WHERE sid = &sid);-- Then at OS level: kill -9 <spid>4. Increase Profile Idle Timeout (if too aggressive)
Section titled “4. Increase Profile Idle Timeout (if too aggressive)”-- Check current settingSELECT limit FROM dba_profilesWHERE profile = 'DEFAULT' AND resource_name = 'IDLE_TIME';
-- Increase idle time to 60 minutes (value is in minutes)ALTER PROFILE default LIMIT IDLE_TIME 60;
-- Or unlimited for service accounts (use with caution)ALTER PROFILE app_profile LIMIT IDLE_TIME UNLIMITED;5. Configure Dead Connection Detection
Section titled “5. Configure Dead Connection Detection”Add to $ORACLE_HOME/network/admin/sqlnet.ora on the database server:
# Probe idle connections every 10 minutesSQLNET.EXPIRE_TIME = 10This ensures Oracle actively detects and cleans up dead connections rather than leaving them as SNIPED sessions consuming resources.
6. Verify Firewall Timeout Alignment
Section titled “6. Verify Firewall Timeout Alignment”If a firewall sits between application and database servers, ensure its TCP idle timeout is longer than SQLNET.EXPIRE_TIME. A firewall that kills the TCP socket before Oracle probes it will cause silent stale connections.
Prevention Strategies
Section titled “Prevention Strategies”1. Implement Robust Reconnect Logic
Section titled “1. Implement Robust Reconnect Logic”-- PL/SQL wrapper with reconnect detectionCREATE OR REPLACE PROCEDURE safe_execute(p_sql IN VARCHAR2) ISBEGIN EXECUTE IMMEDIATE p_sql;EXCEPTION WHEN OTHERS THEN IF SQLCODE = -1012 THEN -- Log the event and signal the caller to reconnect DBMS_OUTPUT.PUT_LINE('Session lost — ORA-01012. Reconnection required.'); RAISE; ELSE RAISE; END IF;END safe_execute;/2. Monitor Stale Session Accumulation
Section titled “2. Monitor Stale Session Accumulation”-- Schedule a job to report SNIPED/KILLED sessionsBEGIN DBMS_SCHEDULER.CREATE_JOB( job_name => 'MONITOR_STALE_SESSIONS', job_type => 'PLSQL_BLOCK', job_action => q'[ DECLARE v_count NUMBER; BEGIN SELECT COUNT(*) INTO v_count FROM v$session WHERE status IN ('KILLED','SNIPED'); IF v_count > 10 THEN -- Insert into monitoring table or send alert INSERT INTO dba_alerts(alert_time, alert_msg) VALUES (SYSDATE, 'Stale sessions: ' || v_count); COMMIT; END IF; END; ]', repeat_interval => 'FREQ=MINUTELY;INTERVAL=15', enabled => TRUE );END;/3. Best Practices Summary
Section titled “3. Best Practices Summary”- Always validate connections on borrow in connection pools
- Configure
SQLNET.EXPIRE_TIMEon the database server to detect dead clients - Align firewall TCP idle timeouts with
SQLNET.EXPIRE_TIME - Set sensible
IDLE_TIMEprofile limits — not zero or unlimited extremes - Log ORA-01012 occurrences in application error handlers to detect patterns
- Use Oracle’s Fast Application Notification (FAN) with FAN-aware drivers to receive instant disconnect events
Related Errors
Section titled “Related Errors”- ORA-01034 - Oracle Not Available (instance is down)
- ORA-01109 - Database Not Open
- ORA-02063 - Database Link Error
- ORA-03113 - End-of-file on Communication Channel
- ORA-01017 - Invalid Username/Password (on reconnect)
Emergency Response
Section titled “Emergency Response”Quick Fixes
Section titled “Quick Fixes”-
Clear all KILLED/SNIPED sessions
BEGINFOR s IN (SELECT sid, serial# FROM v$sessionWHERE status IN ('KILLED','SNIPED')) LOOPEXECUTE IMMEDIATE'ALTER SYSTEM KILL SESSION ''' || s.sid || ',' || s.serial# || ''' IMMEDIATE';END LOOP;END;/ -
Force application reconnection by bouncing the pool
-- In WebLogic / WAS admin console, shrink or restart the connection pool.-- For lightweight JDBC pools, set pool min size to 0 briefly:-- This evicts all cached connections and forces fresh logons. -
Verify database availability before blaming the session
SELECT status, open_mode FROM v$instance, v$database;
Post-Resolution Cleanup
Section titled “Post-Resolution Cleanup”-- Confirm no orphaned sessions remainSELECT COUNT(*), statusFROM v$sessionWHERE username IS NOT NULLGROUP BY status;
-- Review alert log for root cause (network drops, OOM kills, etc.)-- ADRCI: adrci> show alert -tail 100
-- Update sqlnet.ora if dead connection detection was missing-- Then reload the listener: lsnrctl reload