hibiken/asynq · warning
testutil: redis is down
Error message
testutil: redis is down
What it means
errRedisDown is a sentinel error in the internal test broker (TestBroker) that simulates Redis being unavailable. TestBroker wraps a real broker; when its 'sleeping' flag is set (simulated outage, typically via Sleep()/WakeUp() in tests), every broker method including Enqueue, EnqueueUnique, BatchEnqueue, Dequeue, Done, and MarkAsComplete returns this error instead of touching Redis.
Solutions
- If you hit this in your own tests, call the TestBroker method that restores availability (WakeUp) after asserting the down-state behavior.
- If this error is unexpected, check for a leaked Sleep() from a prior test step or missing cleanup (e.g. defer WakeUp).
- In code under test, handle the broker error as a transient outage: rely on asynq's retry/delay mechanisms or surface it to the test as the expected failure.
Example fix
// before tb.Sleep() client.Enqueue(task) // returns "testutil: redis is down" // after tb.Sleep() // ... assertions on failure behavior ... tb.WakeUp() err := client.Enqueue(task) // succeeds again
Defensive patterns
Strategy: try-catch
Validate before calling
if tb, ok := broker.(*testbroker.TestBroker); ok && tb.Sleeping() { /* restore before calling broker methods */ } Type guard
func isRedisDown(err error) bool { return errors.Is(err, errRedisDown) } Try / catch
if err := broker.Enqueue(ctx, msg); err != nil {
if errors.Is(err, errRedisDown) {
t.Fatal("broker used while simulated outage active — call WakeUp first")
}
t.Fatalf("enqueue failed: %v", err)
} Prevention
- Always defer WakeUp when calling Sleep in tests.
- Keep simulated-outage tests self-contained so sleeping state cannot leak to other tests.
- Assert on the specific sentinel error, not generic error equality.
When it happens
Trigger: Calling any broker method on a TestBroker while tb.sleeping is true — i.e. after test code has put the broker into its simulated-down state — or writing tests that call TestBroker.Sleep() and then exercise client/server paths that hit the broker.
Common situations: This error appears only in test environments: unit tests that simulate Redis outages to verify retry/failure handling, or a test that forgot to call the broker's wake-up/restore method after putting it to sleep, causing subsequent operations in the same test to fail unexpectedly.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- task id conflicts with another task
- asynq: could not parse redis uri
- asynq: unsupported uri scheme
- asynq: could not parse redis uri: database number should be…
- redis connection is shared so the Inspector can't be closed…
AI-assisted analysis of hibiken/asynq@d135f1439b (2026-09-07).
Data as JSON: /api/errors/43b134ed82ce429c.
Report an issue: GitHub.
Appendix: source
Thrown at internal/testbroker/testbroker.go:18
// Copyright 2020 Kentaro Hibino. All rights reserved.
// Use of this source code is governed by a MIT license
// that can be found in the LICENSE file.
// Package testbroker exports a broker implementation that should be used in package testing.
package testbroker
import (
"context"
"errors"
"sync"
"time"
"github.com/hibiken/asynq/internal/base"
"github.com/redis/go-redis/v9"
)
var errRedisDown = errors.New("testutil: redis is down")
// TestBroker is a broker implementation which enables
// to simulate Redis failure in tests.
type TestBroker struct {
mu sync.Mutex
sleeping bool
// real broker
real base.Broker
}
// Make sure TestBroker implements Broker interface at compile time.
var _ base.Broker = (*TestBroker)(nil)
func NewTestBroker(b base.Broker) *TestBroker {
return &TestBroker{real: b}
}
View on GitHub (pinned to d135f1439b)