ORA-00600 is Oracle’s catch-all internal error code. A server process hit an unexpected condition inside the kernel and failed an internal assertion. The database may stay up, the failing call rolls back, and the system may look normal for minutes or hours, but the engine has reported a condition you cannot fix from SQL.

The message format is ORA-00600: internal error code, arguments: [kdsgrp1], [], [], [], [], [], [], []. The first bracketed token, here [kdsgrp1], is the internal message number and the single most important input for Oracle Support. Multiple distinct bugs can assert in the same internal function, so the argument narrows the search but does not uniquely identify the bug. The full argument list plus the exact database version, down to patch level, is what Support needs to find the matching known bug.

The alert log records every ORA-00600 with a reference to a trace file in the Automatic Diagnostic Repository (ADR). That trace contains the call stack, the SQL text when applicable, and a block dump for corruption-related asserts. It is the only durable evidence that the error occurred. If the instance is restarted before the trace is captured, the on-disk trace remains, but session-level context (open cursors, bind values, PGA state) is gone.

What this means

Oracle reserves the ORA-006xx range for internal errors that should never occur in normal operation. Three codes appear together in the alert log and are routinely confused:

CodeMeaningOriginSeverity
ORA-00600Internal error code, argumentsOracle kernel assertion failed; usually a bug, occasionally corruption or hardwarePAGE
ORA-07445Exception encountered: core dumpOperating system signal (SIGSEGV, SIGBUS, and similar) caught inside Oracle codePAGE
ORA-00700Soft internal error, argumentsInternal “should not happen” condition handled gracefullyVariable

ORA-00600 and ORA-07445 are treated the same operationally: both are critical, both generate a trace, both require Support engagement. The distinction matters for triage because ORA-07445 points more often at OS-level causes (bad memory, OS bug, storage fault returning bad data) while ORA-00600 points more often at a kernel logic bug or a corrupted block being processed. Capture the same artifacts either way.

Do not bucket ORA-00600 / ORA-07445 with ORA-01555 (a tuning signal) or ORA-04031 (urgent but different from corruption). Any ORA-00600 in production is a PAGE, even a single occurrence against an otherwise healthy instance.

Common causes

CauseWhat it looks likeFirst thing to check
Oracle kernel bugRecurring ORA-00600 with same first argument on a specific SQL pattern or featureAlert log and trace; match first argument against My Oracle Support with exact version
Block corruptionORA-00600 with arguments referencing block reads, accompanied by ORA-01578V$DATABASE_BLOCK_CORRUPTION, RMAN VALIDATE, storage SMART data
Hardware fault (RAM, CPU, storage)Random ORA-00600 or ORA-07445 across unrelated SQL; intermittentdmesg for ECC/EDAC errors, storage controller logs
Bug triggered by upgradeFirst ORA-00600 shortly after upgrade or patch applyRecent change history, optimizer feature changes
Resource starvation edge caseORA-00600 under extreme load (memory pressure, very high cursor count)PGA, shared pool, open cursor counts around the time of error
Recovery issue at startupORA-00600 on instance open after a crash, for example [kcratr_nab_less_than_odr]Alert log recovery section, redo log validity

The first argument is the rough category. The remaining arguments and the trace file are the actual evidence.

Quick checks

Read-only. Run these as soon as ORA-00600 is suspected. None modify database state.

# Tail the alert log for the most recent ORA-00600 entries
adrci exec="show alert -tail 200" | grep -A 20 "ORA-00600"
# Alert log location (generic form):
#   $ORACLE_BASE/diag/rdbms/<db_unique_name>/<instance_name>/trace/alert_<instance>.log
ls -lh $ORACLE_BASE/diag/rdbms/*/*/trace/*.trc | tail -20
-- Confirm the instance is still OPEN after the error
SELECT INSTANCE_NAME, STATUS, DATABASE_STATUS, ACTIVE_STATE, SHUTDOWN_PENDING
FROM V$INSTANCE;
-- List recent critical incidents from ADR (12c+)
SELECT INCIDENT_ID, PROBLEM_KEY, ERROR_FACILITY, ERROR_NUMBER,
       ORIGINATING_TIMESTAMP, STATUS
FROM V$DIAG_INCIDENT
WHERE PROBLEM_KEY LIKE 'ORA 600%'
   OR PROBLEM_KEY LIKE 'ORA 7445%'
ORDER BY ORIGINATING_TIMESTAMP DESC
FETCH FIRST 20 ROWS ONLY;
-- Check for concurrent corruption signals
SELECT FILE#, BLOCK#, BLOCKS, CORRUPTION_TYPE
FROM V$DATABASE_BLOCK_CORRUPTION;
-- Capture exact database version, down to patch level
SELECT BANNER_FULL, CON_ID FROM V$VERSION;
# OS-level evidence of hardware fault (run as the oracle OS user, outside SQL)
# -T requires util-linux dmesg; on other systems drop -T for raw timestamps
dmesg -T | grep -iE "ecc|edac|hardware error|i/o error" | tail -30

If V$DIAG_INCIDENT is unavailable, the alert log plus adrci are sufficient. The alert log is the universal correlation anchor for Oracle incidents.

How to diagnose it

  1. Confirm the error and capture the arguments verbatim. Open the alert log, find the ORA-00600 line, and record the entire argument list, not just the first token. The entry typically reads:

    ORA-00600: internal error code, arguments: [kdsgrp1], [], [], [], [], [], [], []
    Errors in file .../trace/<instance>_ora_<pid>.trc
    

    Copy both lines. The trace path is what you package next.

  2. Verify the instance is still usable. A single ORA-00600 usually rolls back the failing statement; the session survives and the instance stays OPEN. If a background process (DBWn, LGWR, PMON) asserts, the instance will abort and restart. Check V$INSTANCE and the alert log for instance recovery messages.

  3. Pull the trace file before anything else changes. ADR preserves trace files across restarts, but if the trace filesystem fills or retention purges old files, you lose the evidence. Copy the trace off the host to a safe location immediately. Do not rely on the file still being there tomorrow.

  4. Distinguish ORA-00600 from ORA-07445 and ORA-00700. If the alert log shows ORA-07445 instead, the cause is an OS-level signal inside Oracle code (often memory or storage). If ORA-00700, it is a soft internal condition. The triage artifacts are the same; the SR routing differs.

  5. Correlate with concurrent signals. Cross-check the ORA-00600 timestamp against:

    • V$DATABASE_BLOCK_CORRUPTION for recently detected corruption
    • dmesg for ECC, EDAC, or I/O errors in a window around the timestamp
    • Recent DDL, statistics gathering, or upgrade activity in the alert log
    • Redo log switches near the time, since some ORA-00600 variants are recovery-related
  6. Package the incident for Oracle Support. ADR creates an incident automatically. Use ADRCI’s Incident Packaging Service (IPS) to bundle the trace, alert log snippet, and related files into a zip Support can ingest. On systems with Autonomous Health Framework (AHF) or Trace File Analyzer (TFA) installed, the collection path is a single command:

    # SRDC collection for ORA-00600 via TFA / AHF
    tfactl diagcollect -srdc ORA-00600
    <!-- TODO: verify exact tfactl diagcollect flags, time-window arguments, and output path on your AHF version -->
    

    Without AHF, the manual ADRCI IPS path produces the equivalent bundle:

    adrci
    IPS CREATE PACKAGE INCIDENT <incident_id>
    IPS GENERATE PACKAGE <package_id> IN /tmp/ora00600_pkg
    <!-- TODO: verify exact ADRCI IPS syntax and correlation options against your Oracle version -->
    
  7. Open the SR with the right opening data. Include:

    • The exact ORA-00600 line including all arguments
    • Database version (full BANNER_FULL from V$VERSION)
    • Platform and OS version
    • The trace file or the package zip
    • Whether this is the first occurrence or recurring
    • Any recent changes (upgrade, patch, parameter change, statistics gathering)
  8. Do not “fix” by restarting. Restarting does not resolve a kernel bug. It loses session context, clears ASH samples, and may mask a recurrence if the trigger is workload-dependent. If the instance has crashed on its own, that is different: let SMON complete recovery and capture the post-recovery alert log.

flowchart td
  A["Alert log: ORA-00600 line"] --> B["Capture arguments + version verbatim"]
  B --> C["Locate trace file in ADR"]
  C --> D["Copy trace off host"]
  D --> E{"Instance still OPEN?"}
  E -- Yes --> F["Correlate with corruption, dmesg, recent changes"]
  E -- No --> G["Wait for SMON recovery, capture post-recovery log"]
  F --> H["Distinguish 600 vs 7445 vs 700"]
  G --> H
  H --> I["Package via ADRCI IPS or tfactl diagcollect"]
  I --> J["Open SR with arguments, version, trace"]

Metrics and signals to monitor

SignalWhy it mattersWarning sign
Alert log ORA-00600 / ORA-07445 countTrend reveals whether a bug is recurring or hardware is degradingAny non-zero value in production; rising rate is escalation
V$DIAG_INCIDENT with PROBLEM_KEY ORA 600%Programmatic access to incident history with timestampsCluster of incidents with same first argument in a short window
V$DATABASE_BLOCK_CORRUPTION rowsCorruption is a common ORA-00600 trigger; the kernel asserts when reading bad blocksAny row
dmesg ECC / EDAC / I/O errorsHardware faults often surface as ORA-00600 / ORA-07445 before they crash the hostAny new hardware error near an ORA-00600 timestamp
Instance status (V$INSTANCE)A background process asserting can abort the instanceSTATUS cycling STARTED -> MOUNTED -> OPEN unexpectedly
V$VERSION BANNER_FULLExact version is mandatory for matching known bugsVersion change should reset the ORA-00600 baseline
Redo log switch frequencySome ORA-00600 variants are recovery-relatedSwitch spikes near ORA-00600 timestamps
Recent DDL / statistics / parameter changesOptimizer and feature changes are common triggers after upgradesChange window correlation

Fixes, or what you actually do

There is no operator-side fix for an ORA-00600. The action set is narrow.

Preserve evidence and engage Support

The first action. Without the trace and arguments, Support cannot identify the bug. Not optional.

Apply the patch Support identifies

Once Support matches the arguments and version to a known bug, they will point you at a patch. Apply it in the next maintenance window. Track the bug ID against the SR.

Short-term workarounds, Support-directed only

Support may suggest a hidden parameter (_some_feature_enabled = false) or a SQL-level workaround (hint, SQL patch, disabling a feature). Treat these as risk-bearing: an underscore parameter that suppresses the assert may silently disable the feature that triggered it. Keep the SR open until a real patch is applied. Do not promote underscore-parameter workarounds into permanent configuration.

Treat the rare non-bug cases

  • Block corruption as root cause: restore and recover the affected blocks via RMAN Block Media Recovery, then investigate storage health. The ORA-00600 is the symptom; corruption is the cause.
  • Hardware fault as root cause: engage the hardware vendor. Replace DIMMs, HBAs, or disks before chasing a software bug that does not exist.
  • Recovery-related ORA-00600 at startup: not kernel bugs in the usual sense. Follow the MOS note for the specific argument. The fix is usually a recovery procedure, not a patch.

What not to do

  • Do not flush the shared pool. It will not fix a kernel bug and may cause a hard parse storm.
  • Do not restart in the hope the error goes away. It masks recurrence.
  • Do not apply underscore parameters found on a forum without a Support-confirmed bug ID.
  • Do not ignore a single occurrence. Any ORA-00600 in production is a PAGE.

Prevention

  • Patch current. Most ORA-00600 bugs are fixed in later release updates. Running an old, unpatched release is the most common reason for “mysterious” recurring internal errors.
  • Enable block checking. DB_BLOCK_CHECKING = FULL or MEDIUM adds CPU overhead but catches corruption before it triggers ORA-00600 downstream.
  • Enable block checksums. DB_BLOCK_CHECKSUM = FULL detects block damage on read.
  • Validate proactively. Schedule RMAN BACKUP VALIDATE CHECK LOGICAL DATABASE periodically to surface corruption before an ORA-00600 does.
  • Monitor hardware. ECC errors, EDAC reports, and storage SMART data are leading indicators. A failing DIMM produces ORA-00600 / ORA-07445 before it produces a clean crash.
  • Track the trend. A rising rate of ORA-00600 / ORA-07445 over weeks suggests either a regression (recent patch introduced a new bug) or hardware degradation. Use V$DIAG_INCIDENT counts as a trend signal, not just a per-event alert.
  • Stage upgrades. Most post-upgrade ORA-00600 storms come from optimizer or feature changes. Test the upgrade against a production-shaped workload and keep a rollback path.

How Netdata helps

Netdata’s value for ORA-00600 is correlation, not detection of the error itself. The error lives in the alert log; monitoring assembles the surrounding context that explains why it happened.

  • Per-second metric context around the timestamp. CPU saturation, PGA spikes, redo latency, and I/O errors in the minutes before an ORA-00600 narrow the cause from “kernel bug” to “kernel bug triggered under condition X”.
  • OS-level signals alongside database signals. dmesg ECC errors, disk latency outliers, and OOM killer activity correlate with ORA-07445 / ORA-00600 in ways a database-only view cannot.
  • Anomaly detection on incident counts. A baseline of zero ORA-00600 makes any occurrence anomalous. A baseline of occasional makes a cluster a spike.
  • Alert log scraping. Picking up ORA-00600 / ORA-07445 / ORA-01578 / “cannot allocate new log” lines from the alert log is the fastest path from “user complained” to “we already know.”
  • Correlation across instances. In RAC, an ORA-00600 on one node paired with interconnect errors on another tells a different story than an isolated assert.

Netdata’s Oracle Database monitoring with Netdata brings these signals together with per-second metrics and anomaly detection.