mudler/LocalAI · error
ds4 KvCache::Save: ds4_session_save_payload rc=%d err=%s; re
Error message
ds4 KvCache::Save: ds4_session_save_payload rc=%d err=%s; removing %s
What it means
ds4 KV-cache save got past fopen but ds4_session_save_payload() returned non-zero (with its error string in errbuf); the header bytes were already written to the file, so the code fclose()s it and std::remove()s the partial file to prevent a corrupt cache from being loaded later. The final 'wrote ... ok' log is skipped. Non-fatal to generation; the session simply is not cached.
Source
Thrown at backend/cpp/ds4/kv_cache.cpp:197
if (!fp) {
std::fprintf(stderr, "ds4 KvCache::Save: fopen failed: %s\n", std::strerror(errno));
return;
}
char magic[4] = {'D','S','4','G'};
uint32_t version = 1;
uint32_t ctx = static_cast<uint32_t>(ctx_size);
uint32_t prefix_len = static_cast<uint32_t>(rendered_text.size());
std::fwrite(magic, 4, 1, fp);
std::fwrite(&version, 4, 1, fp);
std::fwrite(&ctx, 4, 1, fp);
std::fwrite(&prefix_len, 4, 1, fp);
std::fwrite(rendered_text.data(), prefix_len, 1, fp);
std::fwrite(&payload_bytes, 8, 1, fp);
char errbuf[256] = {0};
int rc = ds4_session_save_payload(session, fp, errbuf, sizeof(errbuf));
std::fclose(fp);
if (rc != 0) {
std::fprintf(stderr, "ds4 KvCache::Save: ds4_session_save_payload rc=%d err=%s; removing %s\n",
rc, errbuf, path.c_str());
std::remove(path.c_str());
} else {
std::fprintf(stderr, "ds4 KvCache::Save: wrote %s ok\n", path.c_str());
}
}
} // namespace ds4cpp
View on GitHub (pinned to 44413a9d06)
Solutions
- Read err in the log line — it is the library's own reason (e.g. write error, bad state) and points at the failing stage.
- Free disk space or move the cache directory to a volume with room for payload_bytes (printed earlier in the 'path=... payload_bytes=...' line) plus margin.
- If it recurs on the same prompt, report a ds4 backend issue with the err string — deterministic serialization failures are backend bugs, not config.
- Treat as performance-only degradation meanwhile: requests still work, only KV prefix reuse is lost.
Defensive patterns
Strategy: try-catch
Validate before calling
// C: check free space against the printed payload_bytes before saving
unsigned long long avail = fs_available_bytes(cache_dir);
if (avail < payload_bytes + (payload_bytes >> 3)) {
fprintf(stderr, "ds4 KvCache::Save: skipping, low disk (%llu < %llu)\n", avail, payload_bytes);
return; // avoid partial write + remove churn
} Try / catch
// callers treat a missing cache file as a soft miss, never an error
if (!std::filesystem::exists(cache_path)) {
// cold path: proceed without prefix reuse
} Prevention
- Provision cache storage at least max-ctx payload size plus 10% headroom.
- Log and alert on repeated 'ds4_session_save_payload rc=' lines with the same err string — deterministic failures are backend bugs worth reporting.
- Because the code removes partial files, never assume a file's presence implies a good save; check for the 'wrote ... ok' line in logs.
When it happens
Trigger: Serialization of the session payload fails mid-write: disk filling up during the write (payload_bytes was measured upfront), an internal DSML/session state error surfaced through errbuf, or the session object being in a state that cannot be serialized after an interrupted generation.
Common situations: Large contexts producing multi-GB payloads hitting ENOSPC mid-write; concurrent saves of the same session; backend bugs in the DSML state machine leaving the session partially updated; ephemeral storage limits in Kubernetes emptyDir.
Related errors
- ds4 KvCache::Save: fopen failed: %s
- ds4-worker: missing value for %s
- ds4-worker: invalid value for %s: %s
- ds4-worker: %s
- ds4-worker: unknown option: %s
AI-assisted analysis of mudler/LocalAI@44413a9d06 (2026-08-15).
Data as JSON: /api/errors/b6d06e4fc36b18b6.
Report an issue: GitHub.