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

  1. Align --receive.replication-factor to the same value on all receiver nodes in the cluster
  2. Check the sending node's configuration vs the receiving node's during a rolling deploy
  3. If lowering the factor intentionally, update the hashring and redeploy the whole cluster consistently
  4. 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

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


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           string

View on GitHub (pinned to 35b8b99117)