weaviate/weaviate · error

too many shards in request (%d > %d)

Error message

too many shards in request (%d > %d)

What it means

The async checkpoint create handler caps how many shard names a single request may carry (replica.AsyncCheckpointMaxShardsPerRequest). Exceeding it returns 400 with "too many shards in request (%d > %d)" from adapters/handlers/rest/clusterapi/indices_replicas.go:1219, bounding per-request fan-out.

Source

Thrown at adapters/handlers/rest/clusterapi/indices_replicas.go:1219

	return 0, nil
}

func (i *replicatedIndices) postAsyncCheckpoint() http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		args := regxAsyncCheckpoint.FindStringSubmatch(r.URL.Path)
		if len(args) != 2 {
			http.Error(w, "invalid URI", http.StatusBadRequest)
			return
		}
		className := args[1]

		var req asyncCheckpointCreateRequest
		if status, err := readAsyncCheckpointBody(w, r, &req); err != nil {
			http.Error(w, err.Error(), status)
			return
		}
		if len(req.Shards) > replica.AsyncCheckpointMaxShardsPerRequest {
			http.Error(w, fmt.Sprintf("too many shards in request (%d > %d)",
				len(req.Shards), replica.AsyncCheckpointMaxShardsPerRequest),
				http.StatusBadRequest)
			return
		}
		if req.CutoffMs <= 0 {
			http.Error(w, "cutoff_ms must be > 0", http.StatusBadRequest)
			return
		}
		if req.CreatedAtMs <= 0 {
			http.Error(w, "created_at_ms must be > 0", http.StatusBadRequest)
			return
		}

		createdAt := time.UnixMilli(req.CreatedAtMs).UTC()
		// Past values are fine (tie-breaker handles them); reject only far-future skew.
		if skew := time.Until(createdAt); skew > replica.AsyncCheckpointCreatedAtSkewTolerance {
			http.Error(w,
				fmt.Sprintf("created_at_ms is too far in the future (%s ahead of this node's clock; tolerance %s)",

View on GitHub (pinned to 75aa4b6d11)

Solutions

  1. Split the shard list into batches of at most replica.AsyncCheckpointMaxShardsPerRequest and issue multiple POSTs.
  2. Update the coordinating client/broadcaster to chunk shard lists automatically.
  3. If the limit is genuinely too low for your shard count, evaluate raising AsyncCheckpointMaxShardsPerRequest in a patched build.

Example fix

// before
postCheckpoint(class, allShards) // len(allShards) > max
// after
for batch := range slices.Chunk(allShards, replica.AsyncCheckpointMaxShardsPerRequest) { postCheckpoint(class, batch) }
Defensive patterns

Strategy: validation

Validate before calling

const maxShards = replica.AsyncCheckpointMaxShardsPerRequest
if len(shards) > maxShards {
	shards = shards[:maxShards] // or split into batches
}

Type guard

func withinShardLimit(shards []string) bool { return len(shards) <= replica.AsyncCheckpointMaxShardsPerRequest }

Try / catch

if resp.StatusCode == 400 && strings.Contains(body, "too many shards in request") {
	return postCheckpointInBatches(shards) // resend in compliant batches
}

Prevention

When it happens

Trigger: POST to /replicas/indices/<class>/async-checkpoint whose JSON body's shards array contains more entries than replica.AsyncCheckpointMaxShardsPerRequest (also indirectly enforced by the 64 KiB body cap).

Common situations: Collections with very many shards where the broadcaster sends all shards at once; scripts checkpointing every shard in a single call; oversized batches after shard-count growth (e.g. dynamic sharding scaled up).

Related errors


AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04). Data as JSON: /api/errors/95c675996f33de44. Report an issue: GitHub.