hibiken/asynq · error

initial call to GetConfigs failed

Error message

initial call to GetConfigs failed: %w

What it means

PeriodicTaskManager.initialSync fails when the very first call to the provider's GetConfigs returns an error. The manager cannot build its scheduler without the initial config list, so startup is aborted and the error is wrapped by Start.

Solutions

  1. Diagnose the wrapped provider error and fix the root cause (connectivity, credentials, schema)
  2. Make the provider resilient: retry transient failures inside GetConfigs before surfacing
  3. Optionally delay Start until the config source is known to be available (health check first)
Defensive patterns

Strategy: retry

Validate before calling

// probe before starting
if _, err := provider.GetConfigs(); err != nil {
    return fmt.Errorf("config source unavailable: %w", err)
}

Try / catch

if err := mgr.Start(); err != nil {
    if isTransient(err) {
        time.Sleep(backoff)
        return mgr.Start()
    }
    return err
}

Prevention

When it happens

Trigger: mgr.p.GetConfigs() returns a non-nil error during Start: provider's backing store (DB, Redis, file, remote API) is unreachable, credentials fail, or the provider itself returns an error by design.

Common situations: Config database down or migrations not applied at boot; network policy blocking the config service in k8s; provider returning errors for empty/locked tables.

Understand the failure class

Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.

Related errors


AI-assisted analysis of hibiken/asynq@d135f1439b (2026-09-07). Data as JSON: /api/errors/a0037edd0464cd2d. Report an issue: GitHub.

Appendix: source

Thrown at periodic_task_manager.go:171

	mgr.s.Shutdown()
}

// Run starts the manager and blocks until an os signal to exit the program is received.
// Once it receives a signal, it gracefully shuts down the manager.
func (mgr *PeriodicTaskManager) Run() error {
	if err := mgr.Start(); err != nil {
		return err
	}
	mgr.s.waitForSignals()
	mgr.Shutdown()
	mgr.s.logger.Debugf("PeriodicTaskManager exiting")
	return nil
}

func (mgr *PeriodicTaskManager) initialSync() error {
	configs, err := mgr.p.GetConfigs()
	if err != nil {
		return fmt.Errorf("initial call to GetConfigs failed: %w", err)
	}
	for _, c := range configs {
		if err := validatePeriodicTaskConfig(c); err != nil {
			return fmt.Errorf("initial call to GetConfigs contained an invalid config: %w", err)
		}
	}
	mgr.add(configs)
	return nil
}

func (mgr *PeriodicTaskManager) add(configs []*PeriodicTaskConfig) {
	for _, c := range configs {
		entryID, err := mgr.s.Register(c.Cronspec, c.Task, c.Opts...)
		if err != nil {
			mgr.s.logger.Errorf("Failed to register periodic task: cronspec=%q task=%q err=%v",
				c.Cronspec, c.Task.Type(), err)
			continue
		}

View on GitHub (pinned to d135f1439b)