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
- 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)
- Re-run migrate_qdrant_collection_to_v3 — already-updated points are skipped because the scroll filter only matches points lacking agent_id
- Pause other heavy jobs (optimization, reindexing) on the collection during migration
- 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
- The migration is idempotent (only points lacking agent_id are touched) — always safe to re-run after a transient failure
- Give the Qdrant key write access, not just read, before starting the V3 upgrade
- Avoid running the migration during collection optimization or heavy ingest windows
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
- Qdrant scroll failed ({status}): {text}
- Qdrant scroll failed ({status}): {text}
- Qdrant collection check failed ({status}): {text}
- Qdrant connection failed: {e}
- Qdrant scroll failed during migration ({status}): {text}
AI-assisted analysis of zeroclaw-labs/zeroclaw@88bb9c8533 (2026-08-23).
Data as JSON: /api/errors/866dafa61455e639.
Report an issue: GitHub.