zeroclaw-labs/zeroclaw · error

Qdrant set payload failed ({status}): {text}

Error message

Qdrant set payload failed ({status}): {text}

What it means

The second network step of migrate_qdrant_collection_to_v3: after a successful scroll page, it POSTs the scrolled point ids to /collections/{collection}/points/payload to set payload agent_id = "default" (QDRANT_DEFAULT_AGENT_ID). This error fires when that set-payload call returns a non-2xx status; the message embeds the HTTP status and response text. Because scroll succeeded first, failures here are usually write-path issues: 403 read-only credentials, 409 collection is being optimized/locked, 429 rate limiting, or points deleted mid-migration (404 Not Found points).

Source

Thrown at crates/zeroclaw-config/src/schema/v2.rs:3262

            let body = serde_json::json!({
                "payload": { "agent_id": QDRANT_DEFAULT_AGENT_ID },
                "points": ids,
            });
            let mut req = client.request(reqwest::Method::POST, &set_url);
            if let Some(key) = api_key {
                req = req.header("api-key", key);
            }
            let resp = req
                .header("Content-Type", "application/json")
                .query(&[("wait", "true")])
                .json(&body)
                .send()
                .await
                .context("[system] Qdrant V3 migration: set payload request failed")?;
            if !resp.status().is_success() {
                let status = resp.status();
                let text = resp.text().await.unwrap_or_default();
                anyhow::bail!("Qdrant set payload failed ({status}): {text}");
            }
            let batch_count = body["points"].as_array().map(|a| a.len()).unwrap_or(0);
            updated += batch_count;
        }

        match page.result.next_page_offset {
            Some(offset) if !offset.is_null() => next_offset = Some(offset),
            _ => break,
        }
    }

    if updated > 0 {
        ::zeroclaw_log::record!(
            INFO,
            ::zeroclaw_log::Event::new(module_path!(), ::zeroclaw_log::Action::Note).with_attrs(
                ::serde_json::json!({
                    "collection": collection,
                    "updated": updated,

View on GitHub (pinned to 88bb9c8533)

Solutions

  1. Check the embedded status: 403 → grant the key write/update permissions on the collection; 429 → slow down or upgrade quota, then re-run (migration is idempotent)
  2. Re-run migrate_qdrant_collection_to_v3 — already-updated points are skipped because the scroll filter only matches points lacking agent_id
  3. Pause other heavy jobs (optimization, reindexing) on the collection during migration
  4. Ensure base_url points at the primary node, not a read-only replica
Defensive patterns

Strategy: retry

Try / catch

let mut backoff = std::time::Duration::from_secs(1);
for attempt in 0..5 {
    match migrate_qdrant_collection_to_v3(&client, &url, &coll, key).await {
        Ok(n) => { println!("migrated {n} points"); break; }
        Err(e) if e.to_string().starts_with("Qdrant set payload failed") && attempt < 4 => {
            tokio::time::sleep(backoff).await; // 409/429 are transient
            backoff *= 2;
        }
        Err(e) => return Err(e),
    }
}

Prevention

When it happens

Trigger: Qdrant API key valid for read but not write (403); concurrent migration or heavy optimization on the collection (409/503); rate-limited Qdrant Cloud tier (429); points removed by another client between scroll and set-payload; oversized batch rejected (413).

Common situations: Running the V3 upgrade on a live production Qdrant under load; read-only replica endpoints configured as base_url; shared Qdrant cluster with strict quotas; two ZeroClaw instances migrating the same collection simultaneously.

Related errors


AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23). Data as JSON: /api/errors/866dafa61455e639. Report an issue: GitHub.