thanos-io/thanos · error
request replica exceeds receiver replication factor
Error message
request replica exceeds receiver replication factor
What it means
errBadReplica is the sentinel returned by Write and receiveOTLPHTTP when an incoming request's replication factor exceeds the receiver's configured replication factor. The handler maps it to http.StatusBadRequest (400) and capnp maps it to WriteError_invalidArgument. It signals a configuration mismatch between sending and receiving Thanos receive nodes.
Solutions
- Align --receive.replication-factor to the same value on all receiver nodes in the cluster
- Check the sending node's configuration vs the receiving node's during a rolling deploy
- If lowering the factor intentionally, update the hashring and redeploy the whole cluster consistently
- Inspect the wrapped error at the write path to confirm which side reports the mismatch
Example fix
// before: sender --receive.replication-factor=5 // after (matched with receivers) --receive.replication-factor=3
Defensive patterns
Strategy: validation
Validate before calling
if reqReplicationFactor > r.replicationFactor {
return fmt.Errorf("request replication factor %d exceeds receiver's %d", reqReplicationFactor, r.replicationFactor)
} Type guard
func isBadReplica(err error) bool {
return errors.Is(errors.Cause(err), errBadReplica)
} Try / catch
err := r.Write(ctx, req)
if err != nil && errors.Is(errors.Cause(err), errBadReplica) {
// do not retry: fix replication-factor configuration first
return http.StatusBadRequest
} Prevention
- Keep --receive.replication-factor identical on every receiver in the cluster
- Add a config-drift check in deployment tooling across receiver replicas
- During rolling updates, deploy receivers before senders when lowering the factor
- Document the cluster-wide factor so new nodes inherit the correct value
When it happens
Trigger: A write request arrives (via Write or receiveOTLPHTTP) whose embedded replication factor (from the sender's --receive.replication-factor) is greater than the local receiver's replication factor, so the receiver cannot honor it.
Common situations: Rolling update where some replicas run a higher --receive.replication-factor than others, hashring rebalancing with mixed configuration, a client configured against a different cluster's settings.
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
- ketama: amount of endpoints needs to be larger than…
- raw resolution must be higher than the minimum block size…
- 5m resolution retention must be higher than the minimum…
- building gRPC client
- preparing command failed
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/33e85d5e19cf5d71.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/receive/handler.go:91
// LimitStatsQueryParam is the query parameter for limiting the amount of returned TSDB stats.
LimitStatsQueryParam = "limit"
// Labels for metrics.
labelSuccess = "success"
labelError = "error"
)
type ReplicationProtocol string
const (
ProtobufReplication ReplicationProtocol = "protobuf"
CapNProtoReplication ReplicationProtocol = "capnproto"
)
var (
// errConflict is returned whenever an operation fails due to any conflict-type error.
errConflict = errors.New("conflict")
errBadReplica = errors.New("request replica exceeds receiver replication factor")
errNotReady = errors.New("target not ready")
errUnavailable = errors.New("target not available")
errValidation = errors.New("validation error")
)
type WriteableStoreAsyncClient interface {
storepb.WriteableStoreClient
RemoteWriteAsync(context.Context, *storepb.WriteRequest, endpointReplica, []int, chan writeResponse, func(error))
// TryRemoteWriteAsync submits the request without blocking. Returns false if the peer's
// worker pool is at capacity; the caller should fall back to RemoteWriteAsync.
TryRemoteWriteAsync(context.Context, *storepb.WriteRequest, endpointReplica, []int, chan writeResponse, func(error)) bool
}
// Options for the web Handler.
type Options struct {
Writer *Writer
ListenAddress stringView on GitHub (pinned to 35b8b99117)