ruvnet/ruflo · error
Invalid KV cache magic: 0x
Error message
Invalid KV cache magic: 0x${magic.toString(16)} What it means
The first u32 of an RVF KV cache file must equal RVKV_MAGIC (0x564B5652, ASCII 'RVKV' little-endian); a different value throws. The bytes at inputPath are not an RVF KV cache — typically a model file or unrelated binary/text data passed as a cache.
Solutions
- Ensure loadKvCache only receives files produced by persistKvCache
- Check the first 4 bytes read 'RVKV' before loading; otherwise regenerate the cache
- Keep caches in a dedicated directory with a distinctive extension so they cannot be confused with models
Defensive patterns
Strategy: validation
Validate before calling
const fh = await open(cachePath, 'r');
const b = Buffer.alloc(4);
await fh.read(b, 0, 4, 0); await fh.close();
if (b.toString('ascii') !== 'RVKV') throw new Error('not an RVF KV cache');
await engine.loadKvCache(cachePath); Type guard
async function isRvkvCache(path: string): Promise<boolean> {
const fh = await open(path, 'r');
const b = Buffer.alloc(4);
const { bytesRead } = await fh.read(b, 0, 4, 0);
await fh.close();
return bytesRead === 4 && b.toString('ascii') === 'RVKV';
} Try / catch
try { await engine.loadKvCache(cachePath); }
catch (e) { if (e instanceof Error && e.message.includes('Invalid KV cache magic')) { await engine.persistKvCache(cachePath); } else throw e; } Prevention
- Use distinct directories/extensions for model files vs cache files
- Only feed loadKvCache files that persistKvCache produced
- Smoke-check magic bytes when caches arrive from shared volumes
When it happens
Trigger: loadKvCache(modelPath) where a .gguf model was given as the cache path; a cache directory shared with another engine's format; a corrupted or empty-but-sized file.
Common situations: Config wiring that swaps model and cache path values; caches from a different appliance version using another format; leftover files with the same extension.
Related errors
- Invalid GGUF magic: 0x
- Unsupported KV cache version
- Invalid RVFA magic: expected "RVFA", got
- KV cache file too small
- KV cache file truncated
AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18).
Data as JSON: /api/errors/705f5458d8beebc2.
Report an issue: GitHub.
Appendix: 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 fa13ee4ad6)