What’s the issue?
SQL Server Agent jobs run scheduled administrative and business tasks such as backups, integrity checks, index maintenance, and ETL processes. A job has its own enabled or disabled state, and each schedule attached to the job also has its own enabled or disabled state. Both must be enabled for the job to run automatically at the intended time.This finding flags two related conditions: a job that is enabled but has no schedule attached at all, and a job that is enabled but whose attached schedule is disabled. In either case, the job will not run on a recurring basis even though it appears active in the job list.
These conditions typically arise from manual changes made during troubleshooting, deployments that did not complete cleanly, or jobs that were intentionally created for ad hoc execution but never properly retired or documented.
Why is this a problem?
A job that does not run on the expected schedule may go unnoticed for a long time, particularly if no one is actively watching for missed executions. When the job exists for a critical purpose (backups, integrity checks, replication agents, ETL processes), the missed runs can have serious consequences, including missing recovery points, undetected corruption, broken downstream data flows, and silent data divergence.The risk is amplified by the appearance that all is well. The job is visible in SQL Server Agent, its status shows as enabled, and casual review of the job list does not reveal anything wrong. Only by drilling into the schedule details does the missing or disabled schedule become apparent, which is a step that ad hoc inspections often skip.
Jobs that are deliberately run only on demand are a legitimate use case, but they should be clearly marked or named so they are not confused with jobs that should be running on a schedule. Without that distinction, the team cannot easily tell which jobs are intentional manual jobs and which are misconfigured scheduled jobs.
What should you do about this?
Identify affected jobs by querying msdb.dbo.sysjobs, msdb.dbo.sysjobschedules, and msdb.dbo.sysschedules. Look for enabled jobs that have no rows in sysjobschedules, and for enabled jobs whose attached schedules have enabled = 0 in sysschedules.For each job, determine its intended purpose. If the job should be running on a schedule, attach a new schedule or enable the existing disabled schedule using SSMS under SQL Server Agent, or with sp_attach_schedule and sp_update_schedule. Confirm the schedule frequency, start time, and any conditions match the original requirement.
If the job is intentionally manual or has been replaced by another mechanism, disable the job itself with EXEC msdb.dbo.sp_update_job @job_name = N’JobName’, @enabled = 0; so its status accurately reflects that it is not running automatically. If the job is no longer needed at all, drop it with EXEC msdb.dbo.sp_delete_job @job_name = N’JobName’; to keep the job list clean.