invoke-ai/InvokeAI · error · NotAMatchError
unrecognized unet in_channels {in_channels} for base '{base}
Error message
unrecognized unet in_channels {in_channels} for base '{base}' What it means
After reading the UNet's first-conv in_channels, only 4 (Normal), 5 (Depth, SD2 only), and 9 (Inpaint) are recognized. Any other channel count — or 5 on a base other than SD2 — raises NotAMatchError because InvokeAI has no variant mapping for it.
Source
Thrown at invokeai/backend/model_manager/configs/main.py:426
state_dict = mod.load_state_dict()
key_name = "model.diffusion_model.input_blocks.0.0.weight"
if key_name not in state_dict:
raise NotAMatchError("unable to determine model variant from state dict")
in_channels = state_dict["model.diffusion_model.input_blocks.0.0.weight"].shape[1]
match in_channels:
case 4:
return ModelVariantType.Normal
case 5:
# Only SD2 has a depth variant
assert base is BaseModelType.StableDiffusion2, f"unexpected unet in_channels 5 for base '{base}'"
return ModelVariantType.Depth
case 9:
return ModelVariantType.Inpaint
case _:
raise NotAMatchError(f"unrecognized unet in_channels {in_channels} for base '{base}'")
@classmethod
def _validate_looks_like_main_model(cls, mod: ModelOnDisk) -> None:
has_main_model_keys = _has_main_keys(mod.load_state_dict())
if not has_main_model_keys:
raise NotAMatchError("state dict does not look like a main model")
class Main_Checkpoint_SD1_Config(Main_SD_Checkpoint_Config_Base, Config_Base):
base: Literal[BaseModelType.StableDiffusion1] = Field(default=BaseModelType.StableDiffusion1)
class Main_Checkpoint_SD2_Config(Main_SD_Checkpoint_Config_Base, Config_Base):
base: Literal[BaseModelType.StableDiffusion2] = Field(default=BaseModelType.StableDiffusion2)
class Main_Checkpoint_SDXL_Config(Main_SD_Checkpoint_Config_Base, Config_Base):
base: Literal[BaseModelType.StableDiffusionXL] = Field(default=BaseModelType.StableDiffusionXL)View on GitHub (pinned to 0b6a024f2f)
Solutions
- Verify the file is a main UNet checkpoint, not a ControlNet/adapter — import ControlNets via their own model type.
- If it is a custom-channel fine-tune, InvokeAI cannot classify it; use the upstream repo tooling instead or patch the input conv back to 4 channels if it is a leftover.
- Check the base resolution: in_channels==5 is only valid for SD2 Depth; ensure the correct base was detected.
- Update InvokeAI in case support for newer channel layouts was added.
Example fix
// sanity check before import
sd = load_file('model.safetensors')
ch = sd['model.diffusion_model.input_blocks.0.0.weight'].shape[1]
assert ch in (4, 5, 9), f'unsupported in_channels {ch}' Defensive patterns
Strategy: validation
Validate before calling
sd = load_file('model.safetensors')
ch = sd['model.diffusion_model.input_blocks.0.0.weight'].shape[1]
if ch not in (4, 5, 9):
print(f'in_channels={ch}: likely a ControlNet/adapter or custom fine-tune, not a main model') Type guard
def has_supported_variant(sd: dict) -> bool:
w = sd.get('model.diffusion_model.input_blocks.0.0.weight')
return w is not None and w.shape[1] in (4, 5, 9) Try / catch
try:
cfg = probe_model(path)
except NotAMatchError as e:
if 'in_channels' in str(e):
print('Import as its proper model type (e.g. ControlNet) instead') Prevention
- Import ControlNets/T2I adapters as their own model type
- Avoid custom-channel fine-tunes unless you know how to serve them
- Check in_channels early when triaging unknown checkpoints
When it happens
Trigger: from_model_on_disk → _get_variant_or_raise with in_channels not in {4,5,9}, or in_channels==5 while the resolved base is not StableDiffusion2 (the assert fires first with a different message only if assertion checks pass differently; the match fallthrough raises this error otherwise).
Common situations: ControlNet or T2I-Adapter weights (extra conditioning channels) mistaken for main checkpoints; custom fine-tunes with modified input convs (e.g. grayscale or 8-channel editors); updated models adding channels (e.g. 8 for image-conditioned edit models).
Related errors
- unable to determine model variant from state dict
- Unrecognized LLLite module name: '{name}'
- State dict appears to be in a legacy ControlNet-LLLite weigh
- State dict contains no LLLite modules (no 'lllite_dit_blocks
- LLLite module '{name}' is missing key '{down_key}'
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/add3ff91a8dd3a47.
Report an issue: GitHub.