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
- Check `error.__cause__` for the underlying parse/I/O error
- Verify file size against the upstream repo (truncated files are the most common cause)
- Re-download the `.safetensors` file with checksum verification
- 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
- Verify file size against the repo listing after download
- Use resumable downloads that validate ranges; delete partial files on failure
- Sanity-check with safe_open before installing
- Beware renamed .bin files masquerading as .safetensors
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
- could not read text_encoder/config.json: {e}
- Video has no decodable frame
- Unable to decode image {image_path}: {e}
- Unsupported model source: '{url}'
- Error scanning model at {checkpoint} for malware. Aborting l
AI-assisted analysis of invoke-ai/InvokeAI@0b6a024f2f (2026-08-29).
Data as JSON: /api/errors/4fdac7c7217f1df1.
Report an issue: GitHub.