Oracle でログインしようとしたときに ORA-28000: the account is locked が出たら、アカウントがロック状態になっています。原因はパスワードの連続失敗、パスワードの期限切れ、DBA による手動ロックなど様々です。
本記事では、ACCOUNT_STATUS の全状態と対処法、ロック原因の特定、解除手順、再発防止策まで解説します。
この記事でわかること
・ACCOUNT_STATUS の全 9 種の意味と対処法
・ORA-28000(ロック)/ ORA-28001(期限切れ)の違い
・ロック原因の特定(監査ログ / DBA_USERS)
・ALTER USER ACCOUNT UNLOCK の実行手順
・EXPIRED 状態のパスワード再設定
・一括ロック解除スクリプト
・FAILED_LOGIN_ATTEMPTS / PASSWORD_LOCK_TIME の見直し
・ACCOUNT_STATUS の全 9 種の意味と対処法
・ORA-28000(ロック)/ ORA-28001(期限切れ)の違い
・ロック原因の特定(監査ログ / DBA_USERS)
・ALTER USER ACCOUNT UNLOCK の実行手順
・EXPIRED 状態のパスワード再設定
・一括ロック解除スクリプト
・FAILED_LOGIN_ATTEMPTS / PASSWORD_LOCK_TIME の見直し
ACCOUNT_STATUS の全状態と対処法
SQL(ユーザーの状態を確認)
-- ユーザーのアカウント状態を確認
SELECT username, account_status, lock_date, expiry_date, profile
FROM dba_users
WHERE username NOT IN ('SYS','SYSTEM','ANONYMOUS','XDB','DBSNMP','AUDSYS')
ORDER BY account_status, username;
| ACCOUNT_STATUS | 意味 | ログイン | 対処法 |
|---|---|---|---|
| OPEN | 正常 | 可能 | 対処不要 |
| LOCKED | DBA が手動でロック | 不可 | ALTER USER … ACCOUNT UNLOCK |
| LOCKED(TIMED) | ログイン失敗で自動ロック | 不可(自動解除あり) | PASSWORD_LOCK_TIME 経過で自動解除、または手動 UNLOCK |
| EXPIRED | パスワード期限切れ | 不可 | ALTER USER … IDENTIFIED BY new_password |
| EXPIRED(GRACE) | 猶予期間中 | 可能(警告あり) | 猶予期間内にパスワード変更 |
| EXPIRED & LOCKED | 期限切れ + ロック | 不可 | IDENTIFIED BY + ACCOUNT UNLOCK |
| EXPIRED(GRACE) & LOCKED | 猶予中 + ロック | 不可 | IDENTIFIED BY + ACCOUNT UNLOCK |
| EXPIRED(GRACE) & LOCKED(TIMED) | 猶予中 + 自動ロック | 不可 | IDENTIFIED BY + ACCOUNT UNLOCK(または自動解除を待つ) |
| EXPIRED & LOCKED(TIMED) | 期限切れ + 自動ロック | 不可 | IDENTIFIED BY + ACCOUNT UNLOCK |
LOCKED と LOCKED(TIMED) の違い
・LOCKED: DBA が
・LOCKED(TIMED): FAILED_LOGIN_ATTEMPTS 超過で自動ロック → PASSWORD_LOCK_TIME 経過で自動解除(手動 UNLOCK も可)
・LOCKED: DBA が
ALTER USER ... ACCOUNT LOCK で手動ロック → 手動 UNLOCK 必須・LOCKED(TIMED): FAILED_LOGIN_ATTEMPTS 超過で自動ロック → PASSWORD_LOCK_TIME 経過で自動解除(手動 UNLOCK も可)
ロック解除の手順
LOCKED の解除
SQL(アカウントのアンロック)
-- DBA または SYS で接続 -- sqlplus / as sysdba -- アカウントをアンロック ALTER USER hr ACCOUNT UNLOCK; -- 確認 SELECT username, account_status FROM dba_users WHERE username = 'HR'; -- account_status = OPEN であれば解除完了
EXPIRED の解除(パスワード再設定)
SQL(パスワード再設定 + アンロック)
-- パスワードの再設定(EXPIRED 解除) ALTER USER hr IDENTIFIED BY new_password; -- EXPIRED & LOCKED の場合はアンロックも同時に ALTER USER hr IDENTIFIED BY new_password ACCOUNT UNLOCK; -- 確認 SELECT username, account_status, expiry_date FROM dba_users WHERE username = 'HR';
LOCKED(TIMED) の解除
SQL(自動解除を待つ or 手動解除)
-- PASSWORD_LOCK_TIME の設定を確認 SELECT resource_name, limit FROM dba_profiles WHERE profile = (SELECT profile FROM dba_users WHERE username = 'HR') AND resource_name = 'PASSWORD_LOCK_TIME'; -- 例: 1(1 日後に自動解除)/ 1/24(1 時間後) -- 手動で即座に解除したい場合 ALTER USER hr ACCOUNT UNLOCK;
ACCOUNT UNLOCK だけでは EXPIRED は解除されない
ACCOUNT_STATUS が EXPIRED & LOCKED の場合、
ACCOUNT_STATUS が EXPIRED & LOCKED の場合、
ALTER USER ... ACCOUNT UNLOCK だけではアカウントは EXPIRED 状態のままです。パスワードも再設定する必要があります。ALTER USER hr IDENTIFIED BY password ACCOUNT UNLOCK で両方同時に解除できます。ロック原因の特定
DBA_USERS で基本情報を確認
SQL(ロック日時の確認)
-- LOCK_DATE でいつロックされたか確認 SELECT username, account_status, lock_date, expiry_date FROM dba_users WHERE account_status LIKE '%LOCKED%' ORDER BY lock_date DESC;
監査ログでログイン失敗を調査
SQL(統合監査: ログイン失敗の履歴)
-- 統合監査(12c 以降)
SELECT dbusername, os_username, userhost,
event_timestamp, return_code
FROM unified_audit_trail
WHERE action_name = 'LOGON'
AND return_code <> 0 -- 0 以外 = 失敗
AND dbusername = 'HR'
ORDER BY event_timestamp DESC
FETCH FIRST 20 ROWS ONLY;
-- return_code の意味:
-- 1017 = パスワード不正
-- 28000 = アカウントロック
-- 28001 = パスワード期限切れ
SQL(伝統的監査: ログイン失敗)
-- 伝統的監査
SELECT username, os_username, userhost,
timestamp, returncode
FROM dba_audit_trail
WHERE action_name = 'LOGON'
AND returncode IN (1017, 28000)
AND username = 'HR'
ORDER BY timestamp DESC;
ログイン失敗の IP アドレスを特定
SQL(どの IP から失敗しているかを集計)
-- IP アドレス別のログイン失敗回数(不正アクセスの調査)
SELECT userhost, dbusername,
COUNT(*) AS fail_count,
MAX(event_timestamp) AS last_attempt
FROM unified_audit_trail
WHERE action_name = 'LOGON'
AND return_code = 1017 -- パスワード不正
AND event_timestamp >= SYSDATE - 7
GROUP BY userhost, dbusername
ORDER BY fail_count DESC;
ロック原因の特定フロー
(1)
(2)
(3) 監査ログで同時刻のログイン失敗を調査
(4)
(5) アプリケーションの接続設定ミス or 不正アクセスの判断
(1)
DBA_USERS.ACCOUNT_STATUS で状態を確認(2)
LOCK_DATE でいつロックされたか確認(3) 監査ログで同時刻のログイン失敗を調査
(4)
USERHOST でどの端末/IP から失敗しているか特定(5) アプリケーションの接続設定ミス or 不正アクセスの判断
よくあるロック原因と対処
| 原因 | 症状 | 対処 |
|---|---|---|
| アプリの接続パスワードが古い | 大量のログイン失敗 → LOCKED(TIMED) | アプリの接続設定を修正 → ACCOUNT UNLOCK |
| パスワードの期限切れ | EXPIRED → ORA-28001 | ALTER USER … IDENTIFIED BY new_password |
| 接続プールの古いセッション | プール内の接続が期限切れパスワードでリトライ | プールのリフレッシュ設定を確認 |
| ブルートフォース攻撃 | 不明な IP から大量の失敗 | 監査ログで IP を特定 → ファイアウォールでブロック |
| DBA が手動ロック | LOCKED(lock_date あり) | 意図的なロックか DBA に確認 → ACCOUNT UNLOCK |
| ユーザーの入力ミス | 数回の失敗で LOCKED(TIMED) | 自動解除を待つか手動 UNLOCK |
一括ロック解除スクリプト
SQL(ロック中の全ユーザーを一括解除)
-- ロック中のユーザーを一括アンロック
BEGIN
FOR rec IN (
SELECT username FROM dba_users
WHERE account_status LIKE '%LOCKED%'
AND username NOT IN ('SYS','SYSTEM','ANONYMOUS','XDB','DBSNMP','AUDSYS')
) LOOP
EXECUTE IMMEDIATE 'ALTER USER ' || rec.username || ' ACCOUNT UNLOCK';
DBMS_OUTPUT.PUT_LINE('Unlocked: ' || rec.username);
END LOOP;
END;
/
SQL(EXPIRED & LOCKED を一括復旧: パスワードは個別に設定必要)
-- EXPIRED 状態のユーザー一覧(パスワード再設定が必要)
SELECT username, account_status, expiry_date
FROM dba_users
WHERE account_status LIKE '%EXPIRED%'
AND username NOT IN ('SYS','SYSTEM','ANONYMOUS','XDB')
ORDER BY expiry_date;
-- 個別にパスワードを再設定 + アンロック
ALTER USER hr IDENTIFIED BY temp_password ACCOUNT UNLOCK;
ALTER USER app_user IDENTIFIED BY temp_password ACCOUNT UNLOCK;
-- ※ パスワードはセキュリティ上、一括自動生成できないため個別設定が必要
一括アンロックは開発環境でのみ推奨
本番環境で全ユーザーを一括アンロックすると、不正アクセスで意図的にロックしたユーザーまで解除してしまうリスクがあります。本番では個別に原因を確認してからアンロックしてください。
本番環境で全ユーザーを一括アンロックすると、不正アクセスで意図的にロックしたユーザーまで解除してしまうリスクがあります。本番では個別に原因を確認してからアンロックしてください。
再発防止策
FAILED_LOGIN_ATTEMPTS / PASSWORD_LOCK_TIME の見直し
SQL(プロファイルのパスワードポリシーを確認・変更)
-- 現在の設定を確認
SELECT profile, resource_name, limit
FROM dba_profiles
WHERE resource_name IN ('FAILED_LOGIN_ATTEMPTS', 'PASSWORD_LOCK_TIME')
ORDER BY profile;
-- デフォルト: FAILED_LOGIN_ATTEMPTS=10, PASSWORD_LOCK_TIME=1(日)
-- ロック時間を 30 分に短縮(頻繁にロックされる環境向け)
ALTER PROFILE DEFAULT LIMIT
FAILED_LOGIN_ATTEMPTS 10
PASSWORD_LOCK_TIME 1/48; -- 1/48 日 = 30 分
-- 開発環境: ロックを無効化
ALTER PROFILE dev_profile LIMIT
FAILED_LOGIN_ATTEMPTS UNLIMITED;
アプリケーション接続ユーザーの対策
SQL(アプリ接続ユーザーの専用プロファイル)
-- アプリ接続ユーザーはロック閾値を高めに設定
CREATE PROFILE app_connection LIMIT
FAILED_LOGIN_ATTEMPTS 20 -- 接続プールのリトライに耐える
PASSWORD_LOCK_TIME 1/96 -- 15 分で自動解除
PASSWORD_LIFE_TIME UNLIMITED; -- アプリ用は期限なし
ALTER USER app_user PROFILE app_connection;
| 対策 | 設定 |
|---|---|
| ロック時間を短縮 | PASSWORD_LOCK_TIME 1/48(30 分)/ 1/96(15 分) |
| 失敗回数の閾値を引き上げ | FAILED_LOGIN_ATTEMPTS 20(接続プール環境) |
| 開発環境でロック無効化 | FAILED_LOGIN_ATTEMPTS UNLIMITED |
| アプリユーザーのパスワード期限を無制限に | PASSWORD_LIFE_TIME UNLIMITED |
| 不正アクセスの検出 | 監査ログで IP 別の失敗回数を定期監視 |
パスワード有効期限の詳細は「パスワードの有効期限を無制限にする方法」、プロファイルの全設定は「ユーザープロファイル完全ガイド」、パスワードポリシーのカスタマイズは「パスワードポリシーをカスタマイズする方法」を参照してください。
関連する ORA エラー
| エラー | 意味 | 対処 |
|---|---|---|
| ORA-28000 | アカウントがロックされている | ALTER USER … ACCOUNT UNLOCK |
| ORA-28001 | パスワードが期限切れ | ALTER USER … IDENTIFIED BY new_password |
| ORA-28002 | パスワードは猶予期間内に期限切れ(警告) | 猶予期間内にパスワードを変更 |
| ORA-01017 | ユーザー名/パスワードが無効 | パスワードを確認。連続失敗するとロックされる |
実務パターン集
パターン(1): アプリ接続エラーで緊急ロック解除
SQL
-- (1) 状態確認 SELECT username, account_status, lock_date FROM dba_users WHERE username = 'APP_USER'; -- LOCKED(TIMED) / lock_date = 2026-03-30 08:15 -- (2) アンロック ALTER USER app_user ACCOUNT UNLOCK; -- (3) 原因調査: 監査ログでログイン失敗を確認 SELECT userhost, COUNT(*) FROM unified_audit_trail WHERE dbusername = 'APP_USER' AND return_code = 1017 AND event_timestamp >= SYSDATE - 1 GROUP BY userhost; -- (4) アプリの接続設定(パスワード)を確認・修正
パターン(2): パスワード期限切れ + ロックの同時解除
SQL
-- EXPIRED & LOCKED の場合 ALTER USER hr IDENTIFIED BY NewSecurePass123 ACCOUNT UNLOCK; -- 確認 SELECT account_status, expiry_date FROM dba_users WHERE username = 'HR'; -- OPEN / expiry_date = 180 日後
パターン(3): 全ロックユーザーの一覧と一括解除(開発環境)
SQL
-- ロック中のユーザー一覧
SELECT username, account_status, lock_date, profile
FROM dba_users
WHERE account_status LIKE '%LOCKED%'
AND username NOT IN ('SYS','SYSTEM')
ORDER BY lock_date;
-- 開発環境: 一括アンロック
BEGIN
FOR rec IN (
SELECT username FROM dba_users
WHERE account_status LIKE '%LOCKED%'
AND username NOT IN ('SYS','SYSTEM','ANONYMOUS','XDB')
) LOOP
EXECUTE IMMEDIATE 'ALTER USER ' || rec.username || ' ACCOUNT UNLOCK';
END LOOP;
END;
/
パターン(4): ロック状態の定期監視
SQL(ロック発生を検知するアラート SQL)
-- LOCKED 状態のユーザーを検知(日次バッチで実行)
SELECT username, account_status, lock_date
FROM dba_users
WHERE account_status LIKE '%LOCKED%'
AND lock_date >= SYSDATE - 1
AND username NOT IN ('SYS','SYSTEM','ANONYMOUS','XDB');
-- 結果があればアラート通知
よくある質問
QLOCKED(TIMED) は何もしなくても自動で解除されますか?
Aはい。
PASSWORD_LOCK_TIME に設定された時間が経過すると自動的に OPEN に戻ります。デフォルトは 1 日(24 時間)です。1/24 なら 1 時間、1/48 なら 30 分で自動解除されます。手動で即座に解除したい場合は ALTER USER ... ACCOUNT UNLOCK を実行してください。QACCOUNT UNLOCK してもまたすぐロックされます
Aアプリケーションが古いパスワードでリトライし続けている可能性が高いです。監査ログで失敗元の IP / ホストを特定し、アプリの接続設定を修正してください。根本原因を解決しないとアンロック後に再びロックされます。
Qパスワードを変更せずに EXPIRED を解除できますか?
A同じパスワードで
ALTER USER hr IDENTIFIED BY 同じパスワード を実行すれば EXPIRED は解除されます。ただし PASSWORD_REUSE 制約がある場合は拒否されることがあります。その場合は一時的に別パスワードにしてから元に戻してください。QSYS ユーザーもロックされることはありますか?
Aはい。DBA_USERS 上は LOCKED になります。ただし
sqlplus / as sysdba(OS 認証)はパスワード認証をバイパスするため、SYS がロックされてもサーバー上からログインできます。QFAILED_LOGIN_ATTEMPTS を UNLIMITED にするのは安全ですか?
Aブルートフォース攻撃への耐性がなくなるため、本番環境では推奨しません。開発環境や、ファイアウォールで IP 制限が厳格に行われている環境であれば許容できます。本番では 10〜20 回程度に設定し、PASSWORD_LOCK_TIME を短め(15〜30 分)にするのがバランスの良い設定です。
Qアカウントロックの履歴はどこに記録されますか?
A監査機能が有効であれば、LOGON の失敗が監査ログ(UNIFIED_AUDIT_TRAIL / DBA_AUDIT_TRAIL)に記録されます。
return_code = 28000(ロック)や 1017(パスワード不正)で検索してください。DBA_USERS の LOCK_DATE 列でロックされた日時も確認できます。まとめ
アカウントロック解除の要点をまとめます。
| 状態 | 対処コマンド |
|---|---|
| LOCKED | ALTER USER user ACCOUNT UNLOCK |
| LOCKED(TIMED) | PASSWORD_LOCK_TIME 経過で自動解除 / ALTER USER user ACCOUNT UNLOCK |
| EXPIRED | ALTER USER user IDENTIFIED BY new_password |
| EXPIRED & LOCKED | ALTER USER user IDENTIFIED BY new_password ACCOUNT UNLOCK |
| ロック原因の特定 | DBA_USERS.LOCK_DATE + 監査ログ(return_code = 1017 / 28000) |
| 再発防止: ロック時間を短縮 | ALTER PROFILE … LIMIT PASSWORD_LOCK_TIME 1/48 |
| 再発防止: アプリ用プロファイル | FAILED_LOGIN_ATTEMPTS 20 + PASSWORD_LIFE_TIME UNLIMITED |
ユーザーの作成と権限付与は「ユーザー作成と権限付与の完全ガイド」、パスワード有効期限は「パスワードの有効期限を無制限にする方法」、接続制限は「ユーザーごとに接続制限を設定する方法」も併せて参照してください。

