ORA-01578 is raised when Oracle reads a data block whose contents fail internal validation. The block is marked corrupt and the read fails. The instance keeps running because corruption rarely crashes it, but every query touching that block errors until the block is repaired or bypassed.

Two risks follow. First, the data in that block is inaccessible or lost. Second, backups may be compromised: RMAN detects corrupt blocks during backup by default (MAXCORRUPT=0), but without proactive VALIDATE you may not know when corruption started or which backup pieces are clean.

The error is also frequently a false alarm on Data Guard standbys: NOLOGGING operations on the primary leave the standby with blocks Oracle reports as corrupt. Telling the two apart is the first decision in any ORA-01578 response.

This article covers read-only triage, the distinction between physical corruption and NOLOGGING-induced corruption, and the repair paths from Block Media Recovery through DBMS_REPAIR.

What this means

The error message names the file number and block number. ORA-01110 usually accompanies it with the datafile name. The block is not necessarily destroyed in the storage sense. It may have a bad checksum, a wrong block number, a scrambled header, or logical inconsistency in its row data.

Two diagnostic categories matter for response:

  • Physical (media) corruption. The bytes on disk are wrong: checksum mismatch, wrong block number, zeroed block, torn write. Storage, host memory, or an Oracle bug is the usual root cause.
  • Logical corruption. The block is structurally valid but internally inconsistent: row data, ITL entries, or row directories disagree. RMAN VALIDATE only catches this with CHECK LOGICAL.

A third category looks identical in the alert log but behaves differently: NOLOGGING-induced corruption. If ORA-26040 (“data block was loaded using NOLOGGING option”) accompanies ORA-01578, the block was loaded on the primary without redo, and a physical standby cannot reconstruct it. No hardware is failing, but the data is unrecoverable without reloading.

flowchart TD
    A["ORA-01578 detected"] --> B{"ORA-26040 present?"}
    B -- Yes --> C["NOLOGGING on standby"]
    B -- No --> D["Media corruption"]
    C --> E["RECOVER NONLOGGED BLOCK or reload"]
    D --> F["RMAN VALIDATE CHECK LOGICAL"]
    F --> G["V$DATABASE_BLOCK_CORRUPTION lists blocks"]
    G --> H["BLOCKRECOVER or DBMS_REPAIR"]

Common causes

CauseWhat it looks likeFirst thing to check
Storage hardware failureORA-01578 on blocks clustered in one LUN or extent rangeOS logs, SMART, EDAC, V$DATABASE_BLOCK_CORRUPTION spread
Bad RAMCorruption scattered across files, sometimes with ORA-00600mcelog, edac-utils, dmesg for ECC errors
NOLOGGING on primary, read on standbyORA-01578 plus ORA-26040 on standby only; primary reads cleanV$DATAFILE.UNRECOVERABLE_TIME
Oracle bugORA-01578 with ORA-00600, often version-specific block format issueAlert log arguments, My Oracle Support
Torn write after host crashSingle block, often following power loss or storage path failureBlock dump, RMAN VALIDATE
DB_BLOCK_CHECKING disabledCorrupt block written to disk undetected; surfaces on later readCurrent parameter value

Quick checks

All read-only and safe to run during an incident.

-- Inventory every known corrupt block (populated by RMAN VALIDATE / ANALYZE / DBVERIFY)
SELECT FILE#, BLOCK#, BLOCKS, CORRUPTION_TYPE
FROM V$DATABASE_BLOCK_CORRUPTION;
-- Resolve file number to datafile name and status
SELECT FILE#, NAME, STATUS FROM V$DATAFILE WHERE FILE# = &file_num;
-- Pull recent ORA-01578 / ORA-01110 / ORA-26040 lines from the XML alert log
SELECT originating_timestamp, message_text
FROM V$DIAG_ALERT_EXT
WHERE message_text LIKE '%ORA-01578%'
   OR message_text LIKE '%ORA-01110%'
   OR message_text LIKE '%ORA-26040%'
ORDER BY originating_timestamp DESC;
-- Recent NOLOGGING exposure per datafile (standby diagnosis)
SELECT FILE#, UNRECOVERABLE_CHANGE#, UNRECOVERABLE_TIME
FROM V$DATAFILE
WHERE UNRECOVERABLE_TIME IS NOT NULL
ORDER BY UNRECOVERABLE_TIME DESC;
-- Was corruption already captured into a backup piece?
SELECT * FROM V$BACKUP_CORRUPTION WHERE COMPLETION_TIME > SYSDATE - 7;
-- Confirm proactive detection parameters
SELECT NAME, VALUE FROM V$PARAMETER
WHERE NAME IN ('db_block_checking', 'db_block_checksum');

How to diagnose it

  1. Confirm whether the corruption is real or a NOLOGGING artifact. On a physical standby, check whether ORA-26040 accompanies ORA-01578. If it does, and the primary reads the same block without error, you have NOLOGGING-induced corruption, not media failure. Skip to the standby NOLOGGING fix path below.

  2. Run RMAN VALIDATE to enumerate every corrupt block. A single ORA-01578 from the application tells you one block is bad. It does not tell you whether neighbors are also affected. Always validate before repairing.

# Validate the whole database (physical corruption only, default behavior)
rman target / <<'EOF'
VALIDATE DATABASE;
EOF

Add CHECK LOGICAL to also catch logical corruption:

# Physical plus logical corruption check
rman target / <<'EOF'
VALIDATE CHECK LOGICAL DATABASE;
EOF
  1. Inspect CORRUPTION_TYPE in V$DATABASE_BLOCK_CORRUPTION. Values include ALL ZERO, FRACTURED, CORRUPT, and LOGICAL. Each type points to a different root cause.

  2. Cross-check with DBVERIFY. DBVERIFY reads the datafile directly from disk, outside Oracle, so it can catch corruption the buffer cache might mask.

# Verify a specific datafile (safe on online files)
dbv file=/u01/oradata/prod/users01.dbf blocksize=8192

DBVERIFY output lists corrupt block ranges with explicit line markers.

  1. Trace the corruption to a cause. Cluster the corrupt blocks by file and extent range. Random scatter across files points to memory or storage subsystem failure. A contiguous range in one file suggests a localized storage event. Check OS logs (dmesg, /var/log/messages), SMART data, SAN multipath health, and mcelog for ECC errors.

  2. Check whether your backups already captured the corruption. If V$BACKUP_CORRUPTION shows the corrupt block in a recent backup piece, that backup is compromised. Your last known-good backup may be older than expected.

Metrics and signals to monitor

SignalWhy it mattersWarning sign
V$DATABASE_BLOCK_CORRUPTION row countDirect corruption inventory after VALIDATEAny non-zero row
Alert log ORA-01578 / ORA-01110 / ORA-26040First-place detection of read failuresAny occurrence
V$BACKUP_CORRUPTIONWhether backups captured bad blocksAny rows
V$COPY_CORRUPTIONImage copy integrityAny rows
V$DATAFILE.UNRECOVERABLE_TIMENOLOGGING exposure on standbyTime newer than last incremental backup
DB_BLOCK_CHECKING parameterProactive in-memory detectionFALSE in production
RMAN backup job statusWhether a recovery path still existsRecent failures or no recent backup
OS storage and memory error countersHardware root causeSMART reallocations, EDAC ECC errors

Fixes

Physical corruption: Block Media Recovery

When you have a valid backup, Block Media Recovery (BMR) is the lowest-impact repair. RMAN recovers only the named blocks from backup plus archive redo, without taking the datafile or tablespace offline.

# Recover specific corrupt blocks
rman target / <<'EOF'
BLOCKRECOVER DATAFILE 5 BLOCK 1234, 1235, 1236;
EOF

Or recover every block listed in V$DATABASE_BLOCK_CORRUPTION:

rman target / <<'EOF'
BLOCKRECOVER CORRUPTION LIST;
EOF

Notes:

  • BMR requires a valid backup and archive redo logs to roll the blocks forward to current SCN.
  • BLOCKRECOVER removes repaired blocks from V$DATABASE_BLOCK_CORRUPTION on completion. Re-run VALIDATE to confirm before closing the incident.
  • If the corrupt block belongs to a critical object in SYSTEM, SYSAUX, or UNDO, engage Oracle Support before improvising.

NOLOGGING-induced corruption on standby

This is the most common ORA-01578 false positive. The primary loaded data with NOLOGGING (direct-path insert, certain DDL, CREATE TABLE AS SELECT with no logging). Redo was not generated for those blocks, so the standby cannot reconstruct them.

On 12.2 and later, RMAN can recover only the nonlogged blocks without shipping the whole datafile:

# On the standby
rman target / <<'EOF'
RECOVER DATABASE NONLOGGED BLOCK;
EOF

On versions prior to 12.2, restore the affected datafile from the primary, or take a fresh incremental backup on the primary and apply it to the standby.

Prevention: set ALTER DATABASE FORCE LOGGING on the primary, or follow any NOLOGGING operation with an incremental backup that is shipped to and applied on the standby.

DBMS_REPAIR when no clean backup exists

Warning: DBMS_REPAIR does not fix corruption. It marks blocks as software-corrupt so DML can skip them. Data in those blocks is permanently lost. Use only when BMR is impossible and the data loss is documented and accepted.

-- One-time setup: repair and orphan key tables
EXEC DBMS_REPAIR.ADMIN_TABLES('REPAIR_TAB', 1, 1, 'USERS');
EXEC DBMS_REPAIR.ADMIN_TABLES('ORPHAN_TAB', 2, 1, 'USERS');

-- Scan a specific object and record corrupt blocks
EXEC DBMS_REPAIR.CHECK_OBJECT('HR', 'EMPLOYEES', NULL, 1, 'REPAIR_TAB');

-- Mark blocks so DML skips them
EXEC DBMS_REPAIR.SKIP_CORRUPT_BLOCKS('HR', 'EMPLOYEES');

Rebuild affected indexes afterward, as orphaned index entries will remain.

Data Recovery Advisor

Historically, RMAN’s Data Recovery Advisor (DRA) provided LIST FAILURE, ADVISE FAILURE, and REPAIR FAILURE automation for corruption incidents. DRA was deprecated in 19c and is desupported in 26ai with no replacement. Do not build new runbooks around DRA if you are on, or plan to upgrade to, 26ai.

Prevention

  • Enable DB_BLOCK_CHECKING. Default is FALSE. Set to MEDIUM or FULL in production. Overhead is roughly 1-10% CPU, but it catches corruption in memory before it reaches disk.
  • Confirm DB_BLOCK_CHECKSUM is TYPICAL or FULL. Default is TYPICAL. Checksums catch the majority of media corruption on read.
  • Schedule regular RMAN VALIDATE runs. VALIDATE CHECK LOGICAL DATABASE weekly catches corruption before it reaches your backup window. Treat it as a backup job: monitor for completion.
  • Set FORCE LOGGING on primary databases with physical standbys. NOLOGGING is the single largest source of standby ORA-01578 plus ORA-26040.
  • Track V$DATAFILE.UNRECOVERABLE_TIME. If it is newer than your last incremental backup, the standby has unrecoverable blocks.
  • Monitor storage and memory health at the OS level. SMART reallocated sector counts, EDAC ECC errors, and SAN path failures precede most real corruption incidents.
  • Test backup recovery quarterly. A backup that completes successfully is not the same as a backup that restores. The first time most teams discover their backups are bad is during a real disaster.

How Netdata helps

ORA-01578 surfaces in the alert log, but the surrounding context (storage errors, memory errors, recent NOLOGGING activity, backup health) determines the repair path. Netdata correlates these signals on a per-second timeline:

  • Alert log parsing surfaces ORA-01578, ORA-01110, and ORA-26040 entries with file and block numbers.
  • OS-level storage metrics (disk error rates, SMART attributes where exposed) let you pin the corruption timestamp to hardware events.
  • Memory ECC counters from EDAC and kernel MCE logs help confirm or rule out bad RAM.
  • RMAN backup job status from V$RMAN_BACKUP_JOB_DETAILS confirms whether your recovery path is intact.
  • V$DATAFILE.UNRECOVERABLE_TIME trending flags NOLOGGING exposure before failover turns it into an incident.
  • V$DATABASE_BLOCK_CORRUPTION row count as a gauge charts repair progress toward zero.

See Oracle Database monitoring with Netdata for setup.