ruvnet/ruflo · error · Error
Invalid KV cache magic: 0x${magic.toString(16)}
Error message
Invalid KV cache magic: 0x${magic.toString(16)} What it means
Thrown by loadKvCache when the first u32 of the cache file is not RVKV_MAGIC. This is the format-identity check for the RVF-compatible KV cache format; a mismatch means the file is not an RVKV cache (e.g. a raw tensor file, a different serializer's output, or random bytes). Runs after the size check.
Source
Thrown at v3/@claude-flow/cli/src/appliance/gguf-engine.ts:392
const footer = createHash('sha256').update(entryData).digest();
const header = Buffer.alloc(44);
header.writeUInt32LE(RVKV_MAGIC, 0);
header.writeUInt32LE(RVKV_VERSION, 4);
modelHash.copy(header, 8);
header.writeUInt32LE(this.kvCache.size, 40);
await writeFile(path, Buffer.concat([header, entryData, footer]));
if (this.config.verbose) console.log(`[gguf-engine] KV cache persisted: ${this.kvCache.size} entries`);
}
/** Restore KV cache from an RVF-compatible binary file. */
async loadKvCache(inputPath: string): Promise<void> {
const data = await readFile(inputPath);
if (data.length < 44) throw new Error('KV cache file too small');
const magic = data.readUInt32LE(0);
if (magic !== RVKV_MAGIC) throw new Error(`Invalid KV cache magic: 0x${magic.toString(16)}`);
const version = data.readUInt32LE(4);
if (version !== RVKV_VERSION) throw new Error(`Unsupported KV cache version: ${version}`);
const entryCount = data.readUInt32LE(40);
let offset = 44;
const entries = new Map<string, Buffer>();
for (let i = 0; i < entryCount; i++) {
if (offset + 8 > data.length) throw new Error('KV cache file truncated');
const keyLen = data.readUInt32LE(offset);
const valLen = data.readUInt32LE(offset + 4);
offset += 8;
if (offset + keyLen + valLen > data.length) throw new Error('KV cache file truncated');
entries.set(data.toString('utf-8', offset, offset + keyLen), Buffer.from(data.subarray(offset + keyLen, offset + keyLen + valLen)));
offset += keyLen + valLen;
}
// Verify footer hash (mandatory)View on GitHub (pinned to 6b01dc5a68)
Solutions
- Confirm the file was produced by persistKvCache of this engine (same RVKV_MAGIC); if not, delete it and regenerate.
- Delete the offending file and let the next persistKvCache recreate it cleanly.
- Keep KV caches in a dedicated directory keyed by model hash so formats do not collide.
- Fall back to a cold cache on magic mismatch instead of propagating the error.
Example fix
// before
await engine.loadKvCache(path);
// after
try {
await engine.loadKvCache(path);
} catch (e) {
if (e instanceof Error && /Invalid KV cache magic/.test(e.message)) {
logger.warn({ path }, 'magic mismatch; deleting stale cache');
await fsUnlink(path).catch(() => {});
} else throw e;
} Defensive patterns
Strategy: fallback
Validate before calling
// Sniff the magic before delegating to loadKvCache:
const fh = await open(path, 'r');
const head = Buffer.alloc(4);
await fh.read(head, 0, 4, 0);
await fh.close();
if (head.readUInt32LE(0) !== RVKV_MAGIC) {
await fsUnlink(path).catch(() => {});
return; // not an RVKV cache; cold start
}
await engine.loadKvCache(path); Type guard
function isRvkfMagic(buf: Buffer): boolean {
return buf.length >= 4 && buf.readUInt32LE(0) === RVKV_MAGIC;
} Try / catch
try {
await engine.loadKvCache(path);
} catch (e) {
if (e instanceof Error && /Invalid KV cache magic/.test(e.message)) {
await fsUnlink(path).catch(() => {});
return;
}
throw e;
} Prevention
- Keep KV caches in a dedicated directory to avoid format collisions.
- Delete and regenerate caches with a foreign magic.
- Cold-start on magic mismatch instead of crashing.
- Do not reuse paths that held other formats.
When it happens
Trigger: Loading a file that is large enough but is not an RVKV cache — e.g. a GGUF model file, a pickle, or a JSON dump saved at the same path. Also fires on a partially overwritten file where only the tail changed.
Common situations: Reusing a path that previously held another format; a misconfigured cache directory mixing formats; a stale cache from an older bridge version that used a different magic (though version mismatch usually catches that).
Related errors
- KV cache file too small
- KV cache file truncated
- KV cache file missing SHA256 footer
- KV cache integrity check failed: hash mismatch
- Invalid GGUF magic: 0x${magic.toString(16)} (expected 0x${GG
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/705f5458d8beebc2.
Report an issue: GitHub.