invoke-ai/InvokeAI · error · RuntimeError

Free disk space {free_space / GB:.2f} GB is not enough for d

Error message

Free disk space {free_space / GB:.2f} GB is not enough for download of {remaining_bytes / GB:.2f} GB.

What it means

Before streaming the body, _do_download checks free space on the destination volume (shutil.disk_usage) against the bytes still needed (total_bytes - bytes already downloaded). If free space is less than remaining bytes, RuntimeError is raised so the download aborts before filling the disk. This protects the host from a disk-full condition that could corrupt other application data.

Source

Thrown at invokeai/app/services/download/download_default.py:564

        if job.download_path.exists() and resume_from == 0:
            existing_size = job.download_path.stat().st_size
            if job.total_bytes > 0 and existing_size == job.total_bytes:
                job.bytes = existing_size
                self._signal_job_started(job)
                self._signal_job_complete(job)
                return
            # Existing file does not match expected size; treat as corrupt and restart.
            self._logger.debug(
                "Resume check: existing file size mismatch; deleting and restarting "
                f"path={job.download_path} existing_size={existing_size} expected={job.total_bytes}"
            )
            job.download_path.unlink()

        free_space = disk_usage(job.download_path.parent).free
        GB = 2**30
        remaining_bytes = max(job.total_bytes - job.bytes, 0)
        if free_space < remaining_bytes:
            raise RuntimeError(
                f"Free disk space {free_space / GB:.2f} GB is not enough for download of {remaining_bytes / GB:.2f} GB."
            )

        # Don't clobber an existing file. See commit 82c2c85202f88c6d24ff84710f297cfc6ae174af
        # for code that instead resumes an interrupted download.
        if job.download_path.exists() and resume_from == 0:
            raise OSError(f"[Errno 17] File {job.download_path} exists")

        # append ".downloading" to the path
        # signal caller that the download is starting. At this point, key fields such as
        # download_path and total_bytes will be populated. We call it here because the might
        # discover that the local file is already complete and generate a COMPLETED status.
        self._signal_job_started(job)

        expected_total = job.total_bytes or job.expected_total_bytes or content_length
        # "range not satisfiable" - local file is at least as large as the remote file
        if resp.status_code == 416 or (expected_total > 0 and job.bytes >= expected_total):
            self._logger.info(f"{job.download_path}: complete file found. Skipping.")

View on GitHub (pinned to 0b6a024f2f)

Solutions

  1. Free disk space on the destination volume (delete old models/caches) and resubmit the download.
  2. Point the download at a volume with enough room (change the models directory / dest path in config).
  3. Pre-check space before submitting: compare shutil.disk_usage(dest).free to the expected file size.
  4. Reduce concurrency — pause other queued downloads that share the same volume.

Example fix

# before: submit and hope
queue.submit(source, dest)

# after: pre-flight space check
import shutil
size = expected_size_bytes  # from metadata or HEAD request
if shutil.disk_usage(dest.parent).free < size:
    raise SystemExit('not enough space; clean up or change dest')
queue.submit(source, dest)
Defensive patterns

Strategy: validation

Validate before calling

import shutil, requests
def has_space(url: str, dest, margin: int = 256 * 2**20) -> bool:
    h = requests.head(url, allow_redirects=True, timeout=10)
    size = int(h.headers.get('Content-Length', 0))
    return shutil.disk_usage(dest if dest.is_dir() else dest.parent).free >= size + margin

Try / catch

try:
    queue.submit(source, dest)
except RuntimeError as e:
    if 'Free disk space' in str(e):
        cleanup_old_models_or_change_dest()
        queue.submit(source, alternate_dest_with_space())

Prevention

When it happens

Trigger: Starting or resuming any download whose remaining size exceeds the free space on the partition containing job.download_path — e.g. an 8 GB model with 5 GB free.

Common situations: Large model checkpoints on small volumes/containers with size-limited Docker volumes; downloads directed to /tmp on a small tmpfs; NAS mounts with quotas; multiple concurrent downloads exhausting shared space.

Related errors


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