๐Ÿ”ด The Error You're Seeing

Confirm this matches your console output. If it does, you're in the right place.

ERROR LOGorg.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.scheduling.TaskScheduler' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

โšก Quick Fix Works 80% of the time

Define a ThreadPoolTaskScheduler bean in your @Configuration class.

@Bean public TaskScheduler taskScheduler() { ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.setPoolSize(5); return scheduler; }

๐Ÿง  Why this Happens

Tap to expand the deep technical explanation

Spring's scheduling engine needs a `TaskScheduler` to execute `@Scheduled` methods. By default, Spring Boot auto-configures one. However, if you customized your context, or you explicitly `@Autowired` a `TaskScheduler` in a non-standard way, Spring might fail to find the default bean.

The HITEC City Parking Spot Analogy:

A train station has a timetable (@Scheduled), but they forgot to hire a dispatcher (TaskScheduler). The trains don't know when to leave because no one is directing them.

๐Ÿ” How to Reproduce Confirm this is your error

Create a `@Service` with `@Autowired private TaskScheduler scheduler;`. Do not define a `@Bean` for it and do not use `@EnableScheduling`. Run the app.

๐Ÿ› ๏ธ Solutions (5 Ways to Fix)

Solution 1โœ“ Most common cause

Define a ThreadPoolTaskScheduler bean

๐Ÿ‘‰ Use this to explicitly provide the scheduler.

Creating a `ThreadPoolTaskScheduler` bean gives Spring a concrete scheduler to inject.

@Configuration public class SchedulerConfig { @Bean public TaskScheduler taskScheduler() { ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.setPoolSize(5); scheduler.setThreadNamePrefix("my-scheduler-"); return scheduler; } }
Solution 2

Add @EnableScheduling

๐Ÿ‘‰ Use this if you are using @Scheduled but forgot to turn it on.

This annotation activates the scheduling engine and auto-registers a default TaskScheduler if one isn't found.

@SpringBootApplication @EnableScheduling public class Application { ... }
Solution 3

Use ScheduledExecutorService instead

๐Ÿ‘‰ Use this if you want to use standard Java concurrency instead of Spring's interface.

Inject the standard Java `ScheduledExecutorService` instead of Spring's `TaskScheduler`.

@Bean public ScheduledExecutorService scheduledExecutorService() { return Executors.newScheduledThreadPool(5); }
Solution 4

Fix conflicting bean names

๐Ÿ‘‰ Use this if you have multiple scheduler beans.

If you defined two TaskScheduler beans, Spring gets confused. Use @Primary on the main one.

@Bean @Primary public TaskScheduler primaryScheduler() { ... }
Solution 5

Do not autowire TaskScheduler manually

๐Ÿ‘‰ Use this if you are overcomplicating your code.

Usually, you don't need to inject TaskScheduler. Just put @Scheduled on your methods and let Spring handle it.

// Just use the annotation: @Scheduled(fixedRate = 5000) public void runJob() { ... } // Remove @Autowired TaskScheduler;

๐Ÿ“‹ Version Notes

Spring Boot 2.x

Auto-configures a default scheduler if needed.

Spring Boot 3.x

Stricter bean resolution, fails fast if multiple candidates exist without @Primary.

๐Ÿ›ก๏ธ How to Prevent This Next Time

If you need custom thread pooling for scheduled tasks, always define a single, explicit `ThreadPoolTaskScheduler` bean.

Course Search
Search across all chapters & stages
๐Ÿ“–

Search the course

Type any topic โ€” branching, stash, rebase, hooks โ€” and jump straight to that chapter.

merge branchesgit stashundo commitrebase