hibiken/asynq · critical
asynq: server cannot run with nil handler
Error message
asynq: server cannot run with nil handler
What it means
Server.Start refuses to start the server when the Handler argument is nil. A nil handler means no task-processing function would be available, so tasks could never be executed; asynq fails fast at startup instead of panicking later when a task arrives.
Solutions
- Pass a non-nil asynq.Handler (e.g. a valid *asynq.ServeMux or custom handler) to Start.
- Check that your handler constructor never returns a nil interface; return an explicit error instead.
- Wrap the handler with asynq.HandlerFunc(func(ctx context.Context, t *asynq.Task) error { ... }) if none exists yet.
Example fix
// before
var h asynq.Handler
srv.Start(h) // h is nil
// after
mux := asynq.NewServeMux()
mux.HandleFunc("email:welcome", handleWelcomeTask)
srv.Start(mux) Defensive patterns
Strategy: validation
Validate before calling
if handler == nil {
return errors.New("cannot start asynq server: handler is nil")
}
return srv.Start(handler) Type guard
func isNilHandler(h asynq.Handler) bool {
return h == nil
} Try / catch
if err := srv.Start(handler); err != nil {
log.Fatalf("asynq start failed: %v", err)
} Prevention
- Construct handlers with asynq.NewServeMux() and register tasks before Start.
- Check constructor errors immediately so a failed handler never reaches Start.
- Add a startup assertion that the handler is non-nil in your server bootstrap function.
When it happens
Trigger: Calling srv.Start(nil), or Start with a variable of interface type Handler whose underlying value is nil (e.g. an uninitialized handler struct pointer assigned to the interface).
Common situations: Handler construction failed earlier but the code ignores the error; a factory returns nil on some config path; handler wiring skipped in tests or scaffolding code.
Related errors
- batch enqueue does not support group tasks
- batch enqueue does not support unique tasks
- redis connection is shared so the Inspector can't be closed…
- asynq
- asynq
AI-assisted analysis of hibiken/asynq@d135f1439b (2026-09-07).
Data as JSON: /api/errors/344382a03c89aad9.
Report an issue: GitHub.
Appendix: source
Thrown at server.go:682
if err := srv.Start(handler); err != nil {
return err
}
srv.waitForSignals()
srv.Shutdown()
return nil
}
// Start starts the worker server. Once the server has started,
// it pulls tasks off queues and starts a worker goroutine for each task
// and then call Handler to process it.
// Tasks are processed concurrently by the workers up to the number of
// concurrency specified in Config.Concurrency.
//
// Start returns any error encountered at server startup time.
// If the server has already been shutdown, ErrServerClosed is returned.
func (srv *Server) Start(handler Handler) error {
if handler == nil {
return fmt.Errorf("asynq: server cannot run with nil handler")
}
srv.processor.handler = handler
if err := srv.start(); err != nil {
return err
}
srv.logger.Info("Starting processing")
srv.heartbeater.start(&srv.wg)
srv.healthchecker.start(&srv.wg)
srv.subscriber.start(&srv.wg)
srv.syncer.start(&srv.wg)
srv.recoverer.start(&srv.wg)
srv.forwarder.start(&srv.wg)
srv.processor.start(&srv.wg)
srv.janitor.start(&srv.wg)
srv.aggregator.start(&srv.wg)
return nilView on GitHub (pinned to d135f1439b)