invoke-ai/InvokeAI · error · NotAMatchError

could not read safetensors header: {e}

Error message

could not read safetensors header: {e}

What it means

`NotAMatchError` `could not read safetensors header: {e}` means `_read_safetensors_keys` raised while reading the safetensors key index — the file has a `.safetensors` extension but its header is unreadable (truncated download, corrupt, not actually safetensors, I/O error). The original exception is chained as `__cause__`.

Source

Thrown at invokeai/backend/model_manager/configs/qwen_vl_encoder.py:149

    format: Literal[ModelFormat.Checkpoint] = Field(default=ModelFormat.Checkpoint)

    @classmethod
    def from_model_on_disk(cls, mod: ModelOnDisk, override_fields: dict[str, Any]) -> Self:
        raise_if_not_file(mod)

        raise_for_override_fields(cls, override_fields)

        # Only safetensors checkpoints are supported as single-file Qwen VL encoders.
        # Reject other extensions cheaply before attempting to read keys.
        if mod.path.suffix != ".safetensors":
            raise NotAMatchError(f"expected a .safetensors file, got {mod.path.suffix or '(no suffix)'}")

        # Read only the key index — a 7GB fp8 encoder weighs ~7GB on disk, but we
        # only need the key names to classify it, not the tensor data.
        try:
            keys = _read_safetensors_keys(mod.path)
        except Exception as e:
            raise NotAMatchError(f"could not read safetensors header: {e}") from e

        if not _has_qwen_vl_keys(keys):
            raise NotAMatchError("state dict does not look like a Qwen2.5-VL/Qwen2-VL checkpoint")

        return cls(**override_fields)

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Check `error.__cause__` for the underlying parse/I/O error
  2. Verify file size against the upstream repo (truncated files are the most common cause)
  3. Re-download the `.safetensors` file with checksum verification
  4. Sanity-check with `python -c "from safetensors import safe_open; safe_open('model.safetensors','pt')"`

Example fix

# before: resumed download left 3GB of a 7GB file
# after
huggingface-cli download <repo> model.safetensors --force-download  # or delete and re-fetch
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
from safetensors import safe_open

def safetensors_header_ok(path: Path) -> bool:
    try:
        with safe_open(path, framework="pt"):
            return True
    except Exception:
        return False

Try / catch

try:
    cfg = QwenVLTextEncoderConfig.from_model_on_disk(mod, override_fields)
except NotAMatchError as e:
    print(f"bad safetensors header: {e.__cause__!r}")  # re-download / verify size
    raise

Prevention

When it happens

Trigger: `from_model_on_disk` single-file probing of a `.safetensors` file whose header cannot be parsed: zero-byte or partially downloaded file, a pickle `.bin` renamed to `.safetensors`, disk/network read failure.

Common situations: Interrupted downloads (HF resume gone wrong), cloud-sync placeholder files not yet materialized, renamed non-safetensors files, storage corruption on external drives.

Related errors


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