mudler/LocalAI · error
Input image must have at least 3 channels, got %d\n
Error message
Input image must have at least 3 channels, got %d\n
What it means
Hard error in the img2img path: the source image decoded successfully but reported fewer than 3 channels (grayscale or palette), and the shim requires RGB input. The buffer is freed and generation aborts with code 1. Note stbi_load was called with req_comp=3 so the pixels are already forced to 3 components — the check uses the file's original channel count, so 1-channel grayscale files are rejected even though RGB data exists.
Source
Thrown at backend/go/stablediffusion-ggml/cpp/gosd.cpp:845
bool has_mask_image = (mask_image != NULL && strlen(mask_image) > 0);
uint8_t* input_image_buffer = NULL;
uint8_t* mask_image_buffer = NULL;
std::vector<uint8_t> default_mask_image_vec;
if (has_input_image) {
fprintf(stderr, "Loading input image: %s\n", src_image);
int c = 0;
int img_width = 0;
int img_height = 0;
input_image_buffer = stbi_load(src_image, &img_width, &img_height, &c, 3);
if (input_image_buffer == NULL) {
fprintf(stderr, "Failed to load input image from '%s'\n", src_image);
return 1;
}
if (c < 3) {
fprintf(stderr, "Input image must have at least 3 channels, got %d\n", c);
free(input_image_buffer);
return 1;
}
// Resize input image if dimensions don't match
if (img_width != width || img_height != height) {
fprintf(stderr, "Resizing input image from %dx%d to %dx%d\n", img_width, img_height, width, height);
uint8_t* resized_image_buffer = (uint8_t*)malloc(height * width * 3);
if (resized_image_buffer == NULL) {
fprintf(stderr, "Failed to allocate memory for resized image\n");
free(input_image_buffer);
return 1;
}
stbir_resize(input_image_buffer, img_width, img_height, 0,
resized_image_buffer, width, height, 0, STBIR_TYPE_UINT8,
3, STBIR_ALPHA_CHANNEL_NONE, 0,View on GitHub (pinned to 44413a9d06)
Solutions
- Convert the image to RGB before upload (most tools: 'convert to 24-bit RGB' or 'mode=RGB')
- If the check is too strict for your pipeline (grayscale works fine as RGB), patch the shim to drop the channel check since stbi_load already returns 3-component data
- Validate channel count client-side for user uploads
Example fix
# before magick scan.png -colorspace Gray scan_gray.png # 1 channel -> rejected # after magick scan.png -type TrueColor scan_rgb.png # 3 channels
Defensive patterns
Strategy: validation
Validate before calling
// Go caller: force RGB before img2img
decode, err := imaging.Open(srcPath) // or image/draw pipeline
if err != nil { return err }
rgb := imaging.Clone(decodingToNRGBA(decode)) // always 3-4 channels now
imaging.Save(rgb, srcPath+".rgb.png") Prevention
- Normalize every uploaded image to 24-bit RGB PNG/JPEG before it reaches the backend
- Remember the check uses the file's original channel count even though pixels are converted to 3-channel on decode
When it happens
Trigger: Passing a grayscale (1-channel) PNG/JPEG or a 2-channel image as the img2img source; palette-indexed images that stb reports with low original channel counts.
Common situations: Scanned documents, medical/imaging pipeline outputs, and alpha-only masks fed directly as img2img sources.
Related errors
- Failed to load input image from '%s'\n
- Invalid LoRA multiplier '%s', skipping\n
- Invalid sample method, using default: %s\n
- Invalid scheduler, using default: %s\n
- Failed to allocate memory for resized image\n
AI-assisted analysis of mudler/LocalAI@44413a9d06 (2026-08-15).
Data as JSON: /api/errors/822807b5e36c1dfd.
Report an issue: GitHub.