invoke-ai/InvokeAI · error · ValueError

Unrecognized SDXL LoRA key prefix

Error message

Unrecognized SDXL LoRA key prefix: '{full_key}'.

What it means

convert_sdxl_keys_to_diffusers_format recognizes SDXL LoRA keys only with known prefixes (lora_, lora_te1_, lora_te2_, etc.). Any key with an unrecognized prefix causes this ValueError, because the converter cannot know which model component the tensor targets.

Solutions

  1. Print the offending key and confirm the file is actually an SDXL LoRA; if not, load it with the converter for its real base model.
  2. Rename the key to a supported prefix (e.g. 'lora_unet_...' or 'lora_te_...') matching the SDXL convention.
  3. Update/patch the conversion utility to handle the new prefix if the trainer's format is legitimately new.

Example fix

// before
'my_custom_model.blocks.0.lora_down.weight': t
// after (SDXL convention)
'lora_unet_blocks_0_lora_down.weight': t
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED = ('lora_', 'lora_te1_', 'lora_te2_')
bad = [k for k in state_dict if not any(k.startswith(p) for p in SUPPORTED)]
if bad:
    raise ValueError(f'keys with unsupported prefixes: {bad[:5]}')

Type guard

def is_sdxl_lora_state_dict(state_dict: dict[str, object]) -> bool:
    return all(isinstance(k, str) and k.startswith(('lora_', 'lora_te1_', 'lora_te2_')) for k in state_dict)

Try / catch

try:
    sd = convert_sdxl_keys_to_diffusers_format(state_dict)
except ValueError as e:
    if str(e).startswith('Unrecognized SDXL LoRA key prefix'):
        logger.error('Wrong model family or mangled key: %s', e)
        # route to the correct converter for the file's base model
    else:
        raise

Prevention

When it happens

Trigger: Calling convert_sdxl_keys_to_diffusers_format (via the SDXL LoRA _load_model path) with a state dict containing a key that starts with none of the supported prefixes, e.g. an unrelated model's key or a novel trainer's naming scheme.

Common situations: Loading an SD1/SD3/Flux LoRA with the SDXL converter; files with custom or vendor-specific prefixes; renamed/mangled keys from a state-dict preprocessing step; LyCORIS keys with unusual module names.

Related errors


AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29). Data as JSON: /api/errors/98573095593408a6. Report an issue: GitHub.

Appendix: source

Thrown at invokeai/backend/patches/lora_conversions/sdxl_lora_conversion_utils.py:54

        if full_key.startswith("lora_unet_"):
            search_key = full_key.replace("lora_unet_", "")
            # Use bisect to find the key in stability_unet_keys that *may* match the search_key's prefix.
            position = bisect.bisect_right(stability_unet_keys, search_key)
            map_key = stability_unet_keys[position - 1]
            # Now, check if the map_key *actually* matches the search_key.
            if search_key.startswith(map_key):
                new_key = full_key.replace(map_key, SDXL_UNET_STABILITY_TO_DIFFUSERS_MAP[map_key])
                new_state_dict[new_key] = value
                converted_count += 1
            else:
                new_state_dict[full_key] = value
                not_converted_count += 1
        elif full_key.startswith("lora_te1_") or full_key.startswith("lora_te2_"):
            # The CLIP text encoders have the same keys in both Stability AI and diffusers formats.
            new_state_dict[full_key] = value
            continue
        else:
            raise ValueError(f"Unrecognized SDXL LoRA key prefix: '{full_key}'.")

    if converted_count > 0 and not_converted_count > 0:
        raise ValueError(
            f"The SDXL LoRA could only be partially converted to diffusers format. converted={converted_count},"
            f" not_converted={not_converted_count}"
        )

    return new_state_dict


# code from
# https://github.com/bmaltais/kohya_ss/blob/2accb1305979ba62f5077a23aabac23b4c37e935/networks/lora_diffusers.py#L15C1-L97C32
def _make_sdxl_unet_conversion_map() -> List[Tuple[str, str]]:
    """Create a dict mapping state_dict keys from Stability AI SDXL format to diffusers SDXL format."""
    unet_conversion_map_layer: list[tuple[str, str]] = []

    for i in range(3):  # num_blocks is 3 in sdxl
        # loop over downblocks/upblocks

View on GitHub (pinned to 0b6a024f2f)