mudler/LocalAI · error
[moss-tts-cpp] ERROR: malloc(%zu) failed\n
Error message
[moss-tts-cpp] ERROR: malloc(%zu) failed\n
What it means
The malloc of n * sizeof(float) bytes for the PCM copy-out buffer failed (OOM at the C heap). Synthesis itself succeeded — engine pcm was produced — but the shim cannot hand a copy to the Go side, so it frees the engine buffer and returns nullptr. Indicates process address-space or memory exhaustion proportional to the generated audio length.
Source
Thrown at backend/go/moss-tts-cpp/cpp/mossttscpp.cpp:96
? reference_wav
: nullptr;
int n = 0, sr = 0;
float *pcm = moss_local_tts(g_local, text, ref, seed, &n, &sr);
if (!pcm || n <= 0) {
fprintf(stderr, "[moss-tts-cpp] ERROR: moss_local_tts failed\n");
if (pcm)
moss_free(pcm);
return nullptr;
}
// Copy into a plain malloc buffer the Go side frees via mtl_pcm_free, then
// release the engine-owned buffer with moss_free (mirrors qwen3-tts-cpp,
// keeping ownership on the C runtime's malloc/free).
size_t bytes = (size_t)n * sizeof(float);
float *buf = (float *)malloc(bytes);
if (!buf) {
fprintf(stderr, "[moss-tts-cpp] ERROR: malloc(%zu) failed\n", bytes);
moss_free(pcm);
return nullptr;
}
memcpy(buf, pcm, bytes);
moss_free(pcm);
if (out_n)
*out_n = n;
if (out_sr)
*out_sr = sr;
return buf;
}
void mtl_pcm_free(float *p) { free(p); }
void mtl_unload(void) {
if (g_local) {
moss_local_free(g_local);View on GitHub (pinned to 44413a9d06)
Solutions
- Reduce requested audio length or chunk long text into multiple shorter syntheses.
- Raise the container/process memory limit or free other loaded backends.
- Stream via chunked output if the engine supports it rather than one giant buffer.
- Check for leaked buffers on the Go side (mtl_pcm_free must be called on every returned pointer).
Defensive patterns
Strategy: validation
Validate before calling
// cap requested length before synthesis so the copy buffer stays bounded
const maxSamples = 48_000 * 300 // ~5 min
if estSamples(text) > maxSamples {
return nil, errors.New("requested audio too long; chunk the text")
} Prevention
- Chunk long text into multiple shorter syntheses.
- Free every returned buffer via mtl_pcm_free to avoid heap growth across requests.
- Size container memory for model weights plus the largest expected audio buffer.
When it happens
Trigger: Very long synthesis (huge n) on a process already near its memory ceiling; cgo/purego process with a fragmented heap; container memory limit hit at the moment of the copy.
Common situations: Generating long-form speech in a memory-capped container alongside resident model weights; 32-bit builds where address space runs out; repeated long generations fragmenting the heap.
Related errors
- [moss-tts-cpp] FATAL: moss_local_load failed\n
- [moss-tts-cpp] ERROR: local_path is required\n
- [moss-tts-cpp] ERROR: codec_path is required\n
- [moss-tts-cpp] ERROR: tokenizer_path is required\n
- [moss-tts-cpp] ERROR: model not loaded\n
AI-assisted analysis of mudler/LocalAI@44413a9d06 (2026-08-15).
Data as JSON: /api/errors/2178175ecf05c547.
Report an issue: GitHub.