Introduction Oracle ORA-28001 `the password has expired` occurs when a database user's password exceeds the lifetime defined in their profile. In Oracle 12c+, the default profile has a 180-day password limit. When application service accounts expire, all application connections fail until the password is reset.
Symptoms - `ORA-28001: the password has expired` on application startup - All connections for a specific user fail simultaneously - `DBA_USERS` shows `ACCOUNT_STATUS = EXPIRED` or `EXPIRED(GRACE)` - Connection pool reports authentication failures for all pooled connections - Application health checks fail with database connection errors
Common Causes - Default profile `PASSWORD_LIFE_TIME` set to 180 days (Oracle 12c+) - No automated password rotation process for service accounts - Application user created with default profile settings - Password expiration grace period expired without action - No monitoring on account expiration dates
Step-by-Step Fix 1. **Check account status and profile": ```sql -- Check expired accounts SELECT username, account_status, expiry_date, profile, lock_date FROM dba_users WHERE account_status LIKE '%EXPIRED%' ORDER BY expiry_date;
-- Check profile password limits SELECT profile, resource_name, limit FROM dba_profiles WHERE resource_name = 'PASSWORD_LIFE_TIME' AND profile IN (SELECT DISTINCT profile FROM dba_users WHERE username = 'APP_USER'); ```
- 1.**Reset the expired password":
- 2.```sql
- 3.ALTER USER app_user IDENTIFIED BY "NewS3cur3P@ss2026!";
-- Unlock the account if it's also locked ALTER USER app_user ACCOUNT UNLOCK; ```
- 1.**Disable password expiration for service accounts":
- 2.```sql
- 3.-- Create a custom profile for service accounts
- 4.CREATE PROFILE app_service_profile LIMIT
- 5.PASSWORD_LIFE_TIME UNLIMITED
- 6.FAILED_LOGIN_ATTEMPTS 10
- 7.PASSWORD_LOCK_TIME 1
- 8.PASSWORD_GRACE_TIME 7;
-- Assign the profile to the service account ALTER USER app_user PROFILE app_service_profile; ```
- 1.**Verify the change":
- 2.```sql
- 3.SELECT
- 4.username,
- 5.account_status,
- 6.expiry_date,
- 7.profile
- 8.FROM dba_users
- 9.WHERE username = 'APP_USER';
-- expiry_date should be NULL for UNLIMITED password life time ```
- 1.**Update the application connection configuration":
- 2.
` - 3.# Update the password in all configuration locations
- 4.# - Application config files
- 5.# - Environment variables
- 6.# - Kubernetes secrets
- 7.# - Connection pool configurations
- 8.
`