gohugoio/hugo · critical
malloc failed for final webp data\n
Error message
malloc failed for final webp data\n
What it means
Printed by genwebp's encodeNRGBAAnimated (webp.c:273) when malloc fails to allocate a buffer to copy the assembled WebPData into Hugo-owned memory. The animation was encoded and assembled successfully, but the final memcpy destination cannot be allocated. The worker clears the WebPData and returns NULL, so the encoded animation is lost. This is a pure out-of-memory condition.
Source
Thrown at internal/warpc/genwebp/webp.c:273
WebPAnimEncoderDelete(enc);
return NULL;
}
WebPData webp_data_out;
WebPDataInit(&webp_data_out);
if (!WebPAnimEncoderAssemble(enc, &webp_data_out))
{
fprintf(stderr, "WebPAnimEncoderAssemble failed\n");
WebPAnimEncoderDelete(enc);
return NULL;
}
WebPAnimEncoderDelete(enc);
*output_size = webp_data_out.size;
uint8_t *webp_data = malloc(*output_size);
if (webp_data == NULL)
{
fprintf(stderr, "malloc failed for final webp data\n");
WebPDataClear(&webp_data_out);
return NULL;
}
memcpy(webp_data, webp_data_out.bytes, *output_size);
WebPDataClear(&webp_data_out);
return webp_data;
}
static uint8_t initDecoderConfig(WebPDecoderConfig *config, WebPData data)
{
if (!WebPInitDecoderConfig(config))
{
return 0;
}
if (WebPGetFeatures(data.bytes, data.size, &config->input) != VP8_STATUS_OK)
{
return 0;View on GitHub (pinned to 52c9bd7908)
Solutions
- Raise the worker memory limit so peak (encoder buffer + copied buffer) fits.
- Reduce animation size to shrink the output.
- Serialize animated encodes so only one lives in memory at a time.
- Fix any upstream leak that reduces available heap before this allocation.
- Consider patching genwebp to hand off the WebPData bytes directly instead of malloc+memcpy (avoiding the 2x peak).
Example fix
// before (conceptual genwebp path): encode then duplicate uint8_t *webp_data = malloc(webp_data_out.size); // fails for large outputs memcpy(webp_data, webp_data_out.bytes, webp_data_out.size); // after: hand off ownership of webp_data_out.bytes to the caller and skip the copy, // OR stream the bytes out via write_blob in chunks instead of one malloc
Defensive patterns
Strategy: fallback
Validate before calling
// Reject animations whose estimated output would exceed available memory.
func canFitAssembled(available, w, h, frames int) bool {
// crude upper bound: assume ~1 byte/pixel per frame for WebP
est := w * h * frames
return est*2 < available // 2x for encoder + copy
} Prevention
- Raise the worker memory limit so the encoder buffer and its copy both fit.
- Serialize animated encodes per worker so only one lives in memory.
- Reduce animation size (frames or resolution) for memory-constrained deployments.
- Consider patching genwebp to hand off WebPData bytes directly instead of malloc+memcpy, halving peak memory.
When it happens
Trigger: The assembled WebP output is large enough that a same-sized malloc fails (the encoder already holds a copy, so peak memory is roughly 2x output size), or the process is under overall memory pressure from concurrent work.
Common situations: Large animated WebP output (tens of MB), workers processing multiple animations concurrently under a tight cgroup, or a memory leak in an earlier iteration that has consumed available heap.
Related errors
- Error creating WebPAnimEncoder\n
- WebPAnimEncoderAdd failed for final frame\n
- WebPAnimEncoderAssemble failed\n
- WebPEncode failed: %d (%s)\n
- WebPPictureImportRGBA failed\n
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/0b378e54dfb2cee5.
Report an issue: GitHub.