Oracle problems
Scheduler Job Failed, Broken or Stuck: What the Log Says, and the Fix
3 November 2026
A Scheduler job fails quietly. The statistics job, the partition maintenance, the nightly load or the purge raises an error at three in the morning, the Scheduler writes it to a log view that nobody opens, and the first sign is a report with yesterday's numbers, a tablespace that filled because the purge did not run, or a job that is BROKEN after failing as many times as it was allowed. The log has the error, the run that failed, the step of a chain that stalled and the job that has been running for nine hours, and the queries below read it in that order.
Which jobs are in trouble
SELECT owner, job_name, state, enabled, failure_count, run_count,
last_start_date, next_run_date
FROM dba_scheduler_jobs
WHERE state IN ('BROKEN', 'FAILED', 'CHAIN_STALLED',
'RETRY SCHEDULED')
OR failure_count > 0
OR (enabled = 'TRUE' AND next_run_date < SYSTIMESTAMP)
ORDER BY last_start_date DESC NULLS LAST;
Oracle's reference lists the states a job can be in: SCHEDULED, RUNNING, SUCCEEDED, FAILED, RETRY SCHEDULED, BROKEN, CHAIN_STALLED, STOPPED, DISABLED, COMPLETED, BLOCKED, RESOURCE_UNAVAILABLE, REMOTE and SOME FAILED. FAILURE_COUNT is the number of times the job has failed to run, and MAX_FAILURES is the number of times it will be allowed to fail before being marked broken. A job that is enabled with a NEXT_RUN_DATE in the past is overdue: either nothing is running jobs, or the previous run has not ended.
What the failed run said
SELECT log_date, owner, job_name, status, error#, run_duration,
additional_info, errors
FROM dba_scheduler_job_run_details
WHERE status <> 'SUCCEEDED'
AND log_date > SYSTIMESTAMP - INTERVAL '7' DAY
ORDER BY log_date DESC;
ERROR# is the Oracle error number, and ERRORS holds the error stack with the line in the procedure that raised it; the two answer most failures without a second query. RUN_DURATION against the earlier rows says whether the job was already slowing down before it failed, and ADDITIONAL_INFO carries the detail the Scheduler had, such as the step of a chain.
What is running, and for how long
SELECT r.owner, r.job_name, r.elapsed_time, r.cpu_used,
r.session_id, r.running_instance, s.sql_id, s.event
FROM dba_scheduler_running_jobs r
LEFT JOIN v$session s ON s.sid = r.session_id
ORDER BY r.elapsed_time DESC;
A job with hours of ELAPSED_TIME and seconds of CPU_USED is waiting, and EVENT says on what: a lock held by another session is the usual answer, and the root blocker query finds who holds it. In RAC, join GV$SESSION on RUNNING_INSTANCE as well.
The step of a chain that stalled
SELECT owner, job_name, chain_name, step_name, state,
error_code, start_date, end_date
FROM dba_scheduler_running_chains
ORDER BY owner, job_name, step_name;
Oracle's reference lists the states of a running chain step: NOT_STARTED, RUNNING, SUCCEEDED, STOPPED, FAILED, SCHEDULED, RETRY SCHEDULED, PAUSED and STALLED. A chain is stalled when no step is running or scheduled and no rule ends the chain, which is nearly always a step that failed with no rule written for its failure.
The legacy jobs
SELECT job, schema_user, broken, failures, last_date, next_date, what
FROM dba_jobs
WHERE broken = 'Y'
OR failures > 0
OR next_date < SYSDATE
ORDER BY next_date;
DBA_JOBS still lists the DBMS_JOB jobs that older applications create. FAILURES counts the failures since the last success, and with BROKEN at Y no attempt is made to run the job at all. One parameter stops both kinds of job at once: with JOB_QUEUE_PROCESSES at 0, Oracle's reference says, DBMS_JOB jobs and Scheduler jobs will not run.
The fix, in order
- Read the error before touching the job.
ERROR#andERRORSname the cause, in the procedure, the data or the space, and a job re-enabled without the cause fixed is broken again by morning. An invalid procedure, a full tablespace and a snapshot too old are the three usual ones. - Re-enable a broken job after the fix, and test it by hand. A job goes
BROKENafterMAX_FAILURESfailures.DBMS_SCHEDULER.ENABLEputs it back on its schedule and resets the counts, andDBMS_SCHEDULER.RUN_JOBruns it once outside the schedule; run in the current session, the job's error comes back to your own session instead of the log. - Unstall the chain, then write the missing rule.
DBMS_SCHEDULER.ALTER_RUNNING_CHAINsets the state of the stuck step so the chain can continue or end, andEVALUATE_RUNNING_CHAINmakes the Scheduler look at the rules again. The lasting fix is a rule for every outcome of every step, including failure. - Stop a job that waits, and fix what it waits on.
DBMS_SCHEDULER.STOP_JOBends the run, withFORCEif it will not stop; the lock it waited on is found with the root blocker query, and the next run goes at a time when the blocker is not there. TheMAX_RUN_DURATIONattribute raises an event when a run exceeds it, so the next nine-hour run is noticed in the first hour. - Make an overdue job run. A job is disabled when created and must be enabled with
DBMS_SCHEDULER.ENABLE; a restored or cloned database brings its jobs with it, enabled as they were; andJOB_QUEUE_PROCESSESat 0 stops every job in the database. The window the job runs in, its job class and its resource plan are the next things to check. - Mend the legacy jobs too.
DBMS_JOB.BROKEN(job, FALSE)puts a broken job back andDBMS_JOB.RUNruns it now; Oracle marks a legacy job broken on its own after 16 failures in a row. Moving the job toDBMS_SCHEDULERgets it a log with the error, whichDBMS_JOBnever had.
See it coming
Radar Engine, the detection layer of Scops, reads the job log of every database each hour: Scheduler jobs and legacy jobs, failed, broken, stalled and overdue, and the time since the last success of each, so a job that has failed twice tonight is a finding in the morning and a job that is broken is a Critical, with the error from the log in the finding:
| Detector | Clock | When it fires |
|---|---|---|
| Job, one finding per job | Hourly. Failed, broken, stalled or overdue scheduler and legacy jobs. | Failing: Warning 6 hours after the last success, Critical after 24. Broken, or a stalled chain: Critical. Overdue: Watch, one day: Warning. |
The finding names the job, its owner, the last success, the error of the last run and the step of a chain that stalled. Scops reads the log views through a read-only account, with nothing installed in the database and no Diagnostics Pack, on Standard Edition 2 as on Enterprise Edition.
Questions
Why is my Scheduler job BROKEN?
It failed as many times as MAX_FAILURES allows, and the Scheduler stopped scheduling it. Fix the cause from the error in DBA_SCHEDULER_JOB_RUN_DETAILS, then DBMS_SCHEDULER.ENABLE puts it back on its schedule and resets the failure count.
Where is the error of a failed Scheduler job?
In DBA_SCHEDULER_JOB_RUN_DETAILS: ERROR# is the Oracle error number, ERRORS the error stack with the line that raised it, and ADDITIONAL_INFO whatever else the Scheduler recorded, such as the chain step.
Why does my job never run at all?
A job is disabled when created and must be enabled; JOB_QUEUE_PROCESSES at 0 stops every job in the database; and a job whose previous run has not ended cannot start the next one. DBA_SCHEDULER_JOBS shows ENABLED, STATE and NEXT_RUN_DATE.
What is a stalled chain?
A chain with no step running or scheduled and no rule that ends it, which the job state shows as CHAIN_STALLED and the step state as STALLED. DBMS_SCHEDULER.ALTER_RUNNING_CHAIN moves it on; a rule for every outcome of every step keeps it from stalling again.
Related problems
- Blocking sessions: find the root blocker
- Invalid objects and unusable indexes
- RMAN backup failed or overdue
- All Oracle problems