hibiken/asynq · error
GroupGracePeriod cannot be less than a second
Error message
GroupGracePeriod cannot be less than a second
What it means
This is a panic thrown at server startup when the asynq Config's GroupGracePeriod is set to a positive but sub-second duration. The library intentionally enforces a minimum of one second because grace periods shorter than that would make group aggregation semantics meaningless. Note that a zero value is tolerated and silently falls back to defaultGroupGracePeriod.
Solutions
- Set cfg.GroupGracePeriod to at least 1*time.Second (e.g. 10*time.Second).
- If you want the default, leave GroupGracePeriod as 0 (zero value) instead of a small duration.
- Validate configuration before constructing the server: reject sub-second values with a clear error message.
- If the value comes from an env var or file, ensure the unit conversion is correct (e.g. strconv.Atoi then time.Duration(ms)*time.Millisecond).
Example fix
// before
cfg := asynq.Config{ GroupGracePeriod: 500 * time.Millisecond }
srv := asynq.NewServer(redisOpt, cfg)
// after
cfg := asynq.Config{ GroupGracePeriod: 10 * time.Second }
srv := asynq.NewServer(redisOpt, cfg) Defensive patterns
Strategy: validation
Validate before calling
func validateGracePeriod(d time.Duration) error {
if d != 0 && d < time.Second {
return fmt.Errorf("GroupGracePeriod must be >= 1s (or 0 for default), got %s", d)
}
return nil
} Try / catch
// Go panics are not catchable via try/catch; optionally recover in main:
func main() {
defer func() {
if r := recover(); r != nil {
log.Fatalf("invalid config: %v", r)
}
}()
srv := asynq.NewServer(opt, cfg)
_ = srv
} Prevention
- Validate all duration config fields at startup before constructing the server.
- Parse durations with time.ParseDuration instead of raw integer conversions.
- Remember zero means 'use default' — do not substitute a tiny duration for it.
- Add a unit test asserting your config loader never emits sub-second nonzero durations.
When it happens
Trigger: Calling asynq.NewServer(redisConnOpt, cfg) with cfg.GroupGracePeriod set to a nonzero duration less than time.Second, e.g. 500*time.Millisecond or 1 time.Nanosecond.
Common situations: Developers converting millisecond-based config values (env vars, YAML) into time.Duration without multiplying by time.Millisecond; assuming any positive duration is valid; confusing GracePeriod with the zero-value fallback behavior.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- asynq: unsupported RedisConnOpt type %T
- inspeq: unsupported RedisConnOpt type %T
- asynq: unsupported RedisConnOpt type %T
- asynq: unsupported RedisConnOpt type %T
- asynq: could not parse redis uri
AI-assisted analysis of hibiken/asynq@d135f1439b (2026-09-07).
Data as JSON: /api/errors/33a9526332f0f153.
Report an issue: GitHub.
Appendix: source
Thrown at server.go:497
var qnames []string
for q := range queues {
qnames = append(qnames, q)
}
shutdownTimeout := cfg.ShutdownTimeout
if shutdownTimeout == 0 {
shutdownTimeout = defaultShutdownTimeout
}
healthcheckInterval := cfg.HealthCheckInterval
if healthcheckInterval == 0 {
healthcheckInterval = defaultHealthCheckInterval
}
// TODO: Create a helper to check for zero value and fall back to default (e.g. getDurationOrDefault())
groupGracePeriod := cfg.GroupGracePeriod
if groupGracePeriod == 0 {
groupGracePeriod = defaultGroupGracePeriod
}
if groupGracePeriod < time.Second {
panic("GroupGracePeriod cannot be less than a second")
}
logger := log.NewLogger(cfg.Logger)
loglevel := cfg.LogLevel
if loglevel == level_unspecified {
loglevel = InfoLevel
}
logger.SetLevel(toInternalLogLevel(loglevel))
rdb := rdb.NewRDB(c)
starting := make(chan *workerInfo)
finished := make(chan *base.TaskMessage)
syncCh := make(chan *syncRequest)
srvState := &serverState{value: srvStateNew}
cancels := base.NewCancelations()
syncer := newSyncer(syncerParams{
logger: logger,
requestsCh: syncCh,View on GitHub (pinned to d135f1439b)