Comfy-Org/ComfyUI · error · RuntimeError
ERROR: VAE is invalid: None\n\nIf the VAE is from a checkpoi
Error message
ERROR: VAE is invalid: None\n\nIf the VAE is from a checkpoint loader node your checkpoint does not contain a valid VAE.
What it means
VAE.throw_exception_if_invalid raises when first_stage_model is None, which happens when VAE.__init__ found no recognizable VAE weights in the state dict (it logs 'No VAE weights detected' and returns with first_stage_model = None) or an explicit VAE=None was passed from a checkpoint loader. Any later encode/decode call first validates through this method, so the user gets a clear message instead of an AttributeError.
Source
Thrown at comfy/sd.py:1085
m, u = self.first_stage_model.load_state_dict(sd, strict=False, assign=self.patcher.is_dynamic())
if len(m) > 0:
logging.warning("Missing VAE keys {}".format(m))
if len(u) > 0:
logging.debug("Leftover VAE keys {}".format(u))
logging.info("VAE load device: {}, offload device: {}, dtype: {}".format(self.device, offload_device, self.vae_dtype))
self.model_size()
def model_size(self):
if self.size is not None:
return self.size
self.size = comfy.model_management.module_size(self.first_stage_model)
return self.size
def throw_exception_if_invalid(self):
if self.first_stage_model is None:
raise RuntimeError("ERROR: VAE is invalid: None\n\nIf the VAE is from a checkpoint loader node your checkpoint does not contain a valid VAE.")
def vae_encode_crop_pixels(self, pixels):
if self.crop_input:
downscale_ratio = self.spacial_compression_encode()
dims = pixels.shape[1:-1]
for d in range(len(dims)):
x = (dims[d] // downscale_ratio) * downscale_ratio
x_offset = (dims[d] % downscale_ratio) // 2
if x != dims[d]:
pixels = pixels.narrow(d + 1, x_offset, x)
if pixels.shape[-1] > self.output_channels:
pixels = pixels[..., :self.output_channels]
elif pixels.shape[-1] < self.output_channels:
if self.pad_channel_value is not None:
if isinstance(self.pad_channel_value, str):
mode = self.pad_channel_valueView on GitHub (pinned to 1c6d8d45b3)
Solutions
- Add a VAELoader node and point it at a standalone VAE file (e.g. sd_xl_vae.safetensors, vae-ft-mse-840000.safetensors) and connect it to the decode node.
- Use a full checkpoint that includes VAE weights instead of the pruned/unet-only file.
- Check the console for 'No VAE weights detected' to confirm the checkpoint lacks VAE keys.
Example fix
# before
# workflow: CheckpointLoaderSimple('flux-unet-only.safetensors') -> VAEDecode -> RuntimeError
# after
# CheckpointLoaderSimple('flux-unet-only.safetensors').MODEL/CLIP -> ...
# VAELoader('ae.safetensors').VAE -> VAEDecode.vae Defensive patterns
Strategy: validation
Validate before calling
vae.throw_exception_if_invalid() # cheap explicit check # or: assert vae.first_stage_model is not None
Type guard
def vae_is_valid(vae) -> bool:
return getattr(vae, 'first_stage_model', None) is not None Try / catch
try:
vae.throw_exception_if_invalid()
except RuntimeError as e:
if 'VAE is invalid' in str(e):
raise SystemExit('Checkpoint has no VAE; connect a VAELoader with a standalone VAE file.')
raise Prevention
- For unet-only or pruned checkpoints, always add a VAELoader node with a standalone VAE file.
- Watch for the 'No VAE weights detected' console warning at load time as an early signal.
When it happens
Trigger: Loading a checkpoint whose state dict contains no VAE keys (diffusion-model-only files, UNET-only safetensors, CLIP+model without VAE); passing a None VAE from CheckpointLoaderSimple into VAEDecode/VAEEncode; loading a Diffusers-format model split that excludes the VAE.
Common situations: Using unet-only or 'diffusion model' checkpoints in a workflow that still has VAEDecode wired; LoRA/pruned checkpoints where the VAE was stripped to save space; forgetting to add a separate VAELoader node.
Related errors
- This Controlnet needs a VAE but none was provided, please us
- VAEEncodeAudio: input audio is None (source video may have n
- Need at least {require_count} hooks to combine, but only had
- Unknown normalization type: {norm_type}
- Unknown activation type: {activation_type}
AI-assisted analysis of Comfy-Org/ComfyUI@1c6d8d45b3 (2026-08-14).
Data as JSON: /api/errors/bff1465fe913b75e.
Report an issue: GitHub.