Skip to content

ORA-15025: Could Not Open Disk - Fix ASM Disk Access Errors

Error Text: ORA-15025: could not open disk "string"

The ORA-15025 error occurs when Oracle ASM cannot open a disk device during diskgroup mount, rebalance, or disk discovery operations. ASM requires direct read/write access to the underlying block devices, and any interruption in that access — from a permissions change, a multipath failover, a missing udev rule, or a stale ASM_DISKSTRING — will trigger this error. The diskgroup may fail to mount entirely, or a running rebalance may abort mid-operation.

  • /dev/oracleasm/disks/ device files owned by root instead of oracle/grid
  • Block device permissions on /dev/sd* or /dev/mapper/* set to 640 instead of 660
  • ORACLE_BASE or grid home ownership changed after patching
  • SELinux or AppArmor blocking the ASM instance from opening the device
  • Discovery string does not match the actual device path after storage reconfiguration
  • Blank or missing ASM_DISKSTRING forcing a full OS scan that cannot locate devices
  • Mismatch between AFD (ASM Filter Driver) discovery string and legacy ASMLib paths
  • Multiple discovery strings defined but one path has become stale
  • Device mapper paths renamed after a SAN zoning change
  • Multipath daemon (multipathd) not running, exposing raw paths instead of /dev/mapper/ aliases
  • DM-Multipath blacklist misconfigured, causing device churn
  • WWID change on a replaced LUN leaving the old alias orphaned
  • oracleasm scandisks not run after adding or replacing LUNs
  • Missing or corrupted ASMLib kernel module (oracleasm module not loaded)
  • udev rule for Oracle ASM (99-oracle-asmdevices.rules) missing after OS upgrade
  • /etc/udev/rules.d/ rules not applied because udevadm trigger was not executed
  • LUN removed or masked on the SAN array without first dropping the disk from ASM
  • Disk returning I/O errors detected before ORA-15025 appears in the alert log
  • HBA firmware issue causing transient path loss
  • Storage path failover incomplete, leaving one path unavailable at mount time
  • ASM instance running as grid user but devices owned by oracle
  • Group membership of asmadmin / asmdba not correctly set
  • /dev/oracleasm/ directory recreated by a script with wrong ownership
-- List all ASM disks and their current status
SELECT
dg.name AS diskgroup,
d.disk_number,
d.name AS disk_name,
d.path,
d.header_status,
d.mount_status,
d.mode_status,
d.state,
ROUND(d.total_mb / 1024, 2) AS total_gb,
ROUND(d.free_mb / 1024, 2) AS free_gb,
d.os_mb
FROM v$asm_disk d
LEFT JOIN v$asm_diskgroup dg ON d.group_number = dg.group_number
ORDER BY dg.name, d.disk_number;
-- Find disks with MISSING or error states
SELECT
disk_number,
name,
path,
header_status,
mount_status,
mode_status,
state,
reads,
writes,
read_errs,
write_errs
FROM v$asm_disk
WHERE mount_status != 'CACHED'
OR mode_status != 'ONLINE'
OR state != 'NORMAL'
ORDER BY disk_number;
-- View current ASM_DISKSTRING parameter
SHOW PARAMETER asm_diskstring;
-- View all ASM parameters from within the ASM instance
SELECT name, value, description
FROM v$parameter
WHERE name IN ('asm_diskstring', 'asm_diskgroups', 'asm_power_limit')
ORDER BY name;
-- Verify which disks were discovered with the current string
SELECT
path,
header_status,
mount_status,
name,
failgroup,
ROUND(total_mb/1024, 2) AS total_gb
FROM v$asm_disk
WHERE header_status = 'MEMBER'
ORDER BY path;
-- Overall diskgroup health
SELECT
group_number,
name,
state,
type,
total_mb,
free_mb,
ROUND((1 - free_mb/NULLIF(total_mb,0))*100, 1) AS pct_used,
usable_file_mb,
offline_disks,
compatibility,
database_compatibility
FROM v$asm_diskgroup
ORDER BY name;
-- Check recent ASM alert log entries via external table (if configured)
-- Review $ORACLE_BASE/diag/asm/+asm/<instance>/trace/alert_+ASM*.log
-- Look for: ORA-15025, ORA-15040, ORA-15042, kfed, kfdhdb
-- Check for disks in OFFLINE state inside diskgroup
SELECT
dg.name AS diskgroup,
d.name AS disk_name,
d.path,
d.mode_status,
d.state,
d.repair_timer
FROM v$asm_disk d
JOIN v$asm_diskgroup dg ON d.group_number = dg.group_number
WHERE d.mode_status = 'OFFLINE'
OR d.state IN ('DROPPING', 'HUNG');
-- Monitor ongoing rebalance or mount operations
SELECT
group_number,
operation,
state,
power,
actual,
sofar,
est_work,
est_rate,
est_minutes
FROM v$asm_operation
ORDER BY group_number;

Step 1: Check the Alert Log for the Exact Device Path

Section titled “Step 1: Check the Alert Log for the Exact Device Path”

The ORA-15025 message names the specific disk path that failed. Locate the alert log:

Terminal window
# Find the ASM alert log
find $ORACLE_BASE/diag/asm -name "alert_+ASM*.log" | head -5
# Tail the log for recent errors
tail -200 $ORACLE_BASE/diag/asm/+asm/+ASM1/trace/alert_+ASM1.log | grep -E "ORA-|15025|15040|15042"

Step 2: Verify Device Existence and Permissions

Section titled “Step 2: Verify Device Existence and Permissions”
Terminal window
# List ASMLib managed disks
/usr/sbin/oracleasm listdisks
# Scan for new or changed disks
/usr/sbin/oracleasm scandisks
# Query disk attributes
/usr/sbin/oracleasm querydisk -d DATA01
# Check raw block device permissions (non-ASMLib / udev setup)
ls -la /dev/sd* /dev/mapper/asm* 2>/dev/null
# Check ownership of /dev/oracleasm/ disk entries
ls -la /dev/oracleasm/disks/

Expected ownership for a grid/ASMLib setup:

crw-rw---- 1 grid asmadmin ... /dev/oracleasm/disks/DATA01
Terminal window
# For raw block devices — set correct ownership and mode
chown grid:asmadmin /dev/sdc /dev/sdd
chmod 660 /dev/sdc /dev/sdd
# Reload udev rules if using udev-based ASM disk management
udevadm control --reload-rules
udevadm trigger --type=devices --action=change
# For ASMLib — reinitialize if needed
/usr/sbin/oracleasm configure -i
# Answer prompts: ASM user = grid, ASM group = asmadmin, etc.
/usr/sbin/oracleasm init
/usr/sbin/oracleasm scandisks
-- Connect to ASM instance as SYSASM
-- sqlplus / as sysasm
-- Update the discovery string to match device paths
ALTER SYSTEM SET asm_diskstring = '/dev/oracleasm/disks/*', '/dev/mapper/asm*' SCOPE=BOTH;
-- After updating, force rediscovery by attempting to mount
ALTER DISKGROUP data MOUNT;
Terminal window
# Verify multipathd is running
systemctl status multipathd
# List multipath devices and confirm aliases
multipath -ll
# Show which device corresponds to which WWID
multipathd show paths
multipathd show maps
# Reload multipath configuration if aliases changed
systemctl reload multipathd
-- After resolving the device access issue, mount the diskgroup
ALTER DISKGROUP data MOUNT;
-- If MOUNT fails, try FORCE mount (use with caution — requires all disks visible)
ALTER DISKGROUP data MOUNT FORCE;
-- Check mount result
SELECT name, state FROM v$asm_diskgroup;

Step 7: Mark Offline Disks Online (if disk temporarily disappeared)

Section titled “Step 7: Mark Offline Disks Online (if disk temporarily disappeared)”
-- If the disk came back but is OFFLINE
ALTER DISKGROUP data ONLINE DISK DATA_0003;
-- Or online all disks in the diskgroup
ALTER DISKGROUP data ONLINE ALL;
Terminal window
# Example udev rule for ASM disks — /etc/udev/rules.d/99-oracle-asmdevices.rules
# Identify disks by WWID to survive device rename
KERNEL=="sd*", ENV{ID_WWN}=="0x600508b1001c123456789abcdef01234", \
SYMLINK+="oracleasm/disks/DATA01", OWNER="grid", GROUP="asmadmin", MODE="0660"
# Apply after creating or editing the file
udevadm control --reload-rules && udevadm trigger

2. Monitor Disk Availability with a Scheduled Query

Section titled “2. Monitor Disk Availability with a Scheduled Query”
-- Create a procedure to alert on disk access issues
CREATE OR REPLACE PROCEDURE check_asm_disk_access AS
v_count NUMBER;
BEGIN
SELECT COUNT(*)
INTO v_count
FROM v$asm_disk
WHERE mount_status != 'CACHED'
OR mode_status != 'ONLINE'
OR state != 'NORMAL';
IF v_count > 0 THEN
-- Replace with your preferred alerting mechanism
RAISE_APPLICATION_ERROR(-20001,
'ASM disk access issue detected: ' || v_count || ' disk(s) not healthy.');
END IF;
END;
/
-- Schedule the check every 5 minutes
BEGIN
DBMS_SCHEDULER.CREATE_JOB(
job_name => 'CHECK_ASM_DISK_ACCESS',
job_type => 'STORED_PROCEDURE',
job_action => 'check_asm_disk_access',
repeat_interval => 'FREQ=MINUTELY;INTERVAL=5',
enabled => TRUE
);
END;
/
-- Ensure diskgroup and database compatibility levels are current
SELECT
name,
compatibility,
database_compatibility
FROM v$asm_diskgroup
ORDER BY name;
-- Check for disks with errors accumulating (early warning)
SELECT
name, path, read_errs, write_errs,
ROUND(read_errs + write_errs) AS total_errors
FROM v$asm_disk
WHERE read_errs + write_errs > 0
ORDER BY total_errors DESC;
  • Always run oracleasm scandisks after any SAN LUN presentation or replacement
  • Use persistent device names (WWID-based udev aliases or ASMLib) instead of /dev/sd* paths which can change across reboots
  • Test disk visibility from all cluster nodes before mounting a diskgroup
  • Document the ASM_DISKSTRING value and store it in your runbook; an empty string triggers a full OS scan and can be very slow on large servers
  • Use Oracle’s kfed utility to verify disk headers before attempting forced mounts
  • ORA-15001 — Diskgroup does not exist or is not mounted
  • ORA-15017 — Diskgroup cannot be mounted
  • ORA-15040 — Diskgroup is incomplete (not all disks found)
  • ORA-15032 — Not all alterations performed (partial disk operations)
  • ORA-15041 — Diskgroup space is not sufficient
  • ORA-15042 — ASM disk is missing from diskgroup
  • ORA-15063 — ASM insufficient number of disks in diskgroup
  1. Confirm the disk path from the alert log

    Terminal window
    grep "15025\|could not open disk" \
    $ORACLE_BASE/diag/asm/+asm/+ASM1/trace/alert_+ASM1.log | tail -20
  2. Re-scan ASMLib disks immediately

    Terminal window
    /usr/sbin/oracleasm scandisks && /usr/sbin/oracleasm listdisks
  3. Attempt diskgroup mount after fixing permissions

    ALTER DISKGROUP data MOUNT;
    SELECT name, state FROM v$asm_diskgroup;
-- Verify all disks are healthy after recovery
SELECT name, path, header_status, mount_status, mode_status, state
FROM v$asm_disk
ORDER BY name;
-- Check for any orphaned OFFLINE disks that may have repair timers running
SELECT name, path, mode_status, state, repair_timer
FROM v$asm_disk
WHERE repair_timer > 0;
-- If repair timer is running and disk is confirmed unavailable, drop it
-- ALTER DISKGROUP data DROP DISK DATA_0003 FORCE;
-- WARNING: Only run the above if ASM has enough redundancy to survive the drop