{"record":{"id":"4fdac7c7217f1df1","repo":"invoke-ai/InvokeAI","slug":"could-not-read-safetensors-header-e","errorCode":null,"errorMessage":"could not read safetensors header: {e}","messagePattern":"could not read safetensors header: (.+?)","errorType":"validation","errorClass":"NotAMatchError","httpStatus":null,"severity":"error","filePath":"invokeai/backend/model_manager/configs/qwen_vl_encoder.py","lineNumber":149,"sourceCode":"    format: Literal[ModelFormat.Checkpoint] = Field(default=ModelFormat.Checkpoint)\n\n    @classmethod\n    def from_model_on_disk(cls, mod: ModelOnDisk, override_fields: dict[str, Any]) -> Self:\n        raise_if_not_file(mod)\n\n        raise_for_override_fields(cls, override_fields)\n\n        # Only safetensors checkpoints are supported as single-file Qwen VL encoders.\n        # Reject other extensions cheaply before attempting to read keys.\n        if mod.path.suffix != \".safetensors\":\n            raise NotAMatchError(f\"expected a .safetensors file, got {mod.path.suffix or '(no suffix)'}\")\n\n        # Read only the key index — a 7GB fp8 encoder weighs ~7GB on disk, but we\n        # only need the key names to classify it, not the tensor data.\n        try:\n            keys = _read_safetensors_keys(mod.path)\n        except Exception as e:\n            raise NotAMatchError(f\"could not read safetensors header: {e}\") from e\n\n        if not _has_qwen_vl_keys(keys):\n            raise NotAMatchError(\"state dict does not look like a Qwen2.5-VL/Qwen2-VL checkpoint\")\n\n        return cls(**override_fields)\n","sourceCodeStart":131,"sourceCodeEnd":155,"githubUrl":"https://github.com/invoke-ai/InvokeAI/blob/0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06/invokeai/backend/model_manager/configs/qwen_vl_encoder.py#L131-L155","documentation":"`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__`.","triggerScenarios":"`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.","commonSituations":"Interrupted downloads (HF resume gone wrong), cloud-sync placeholder files not yet materialized, renamed non-safetensors files, storage corruption on external drives.","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')\"`"],"exampleFix":"# before: resumed download left 3GB of a 7GB file\n# after\nhuggingface-cli download <repo> model.safetensors --force-download  # or delete and re-fetch","handlingStrategy":"validation","validationCode":"from pathlib import Path\nfrom safetensors import safe_open\n\ndef safetensors_header_ok(path: Path) -> bool:\n    try:\n        with safe_open(path, framework=\"pt\"):\n            return True\n    except Exception:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    cfg = QwenVLTextEncoderConfig.from_model_on_disk(mod, override_fields)\nexcept NotAMatchError as e:\n    print(f\"bad safetensors header: {e.__cause__!r}\")  # re-download / verify size\n    raise","preventionTips":["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"],"tags":["safetensors","corrupt-file","model-install"],"backgroundTag":"corrupt-model-file","analyzedSha":"0b6a024f2ff6a86bfb953dcdb9cc504ef7397a06","analyzedAt":"2026-08-29T04:46:49.967Z","schemaVersion":2},"datasetVersion":"2026-08-29T07:17:48.351Z"}