unslothai/unsloth · error · RuntimeError

sd-cli (stable-diffusion.cpp) binary is unavailable.

Error message

sd-cli (stable-diffusion.cpp) binary is unavailable.

What it means

Raised when ensure_sd_cpp_binary() returns no binary: the engine could not obtain a usable sd-cli. This happens when auto-install is switched off (or suppressed because the managed tree is in use) and no usable binary already exists, or when installation was attempted and failed. Note this path is also the fallback when a GPU sd-server fails to start, so a broken server install can surface here.

Source

Thrown at studio/backend/core/inference/sd_cpp_backend.py:1077

        from core.inference.diffusion_engine_router import _install_accelerator_for
        return _install_accelerator_for(
            getattr(resolve_diffusion_device_target(), "backend", "cpu")
        )

    def _resolve_engine(self) -> SdCppEngine:
        """The SdCppEngine, installing the binary on first use. Raises if unusable."""
        if self._engine is not None and self._engine.is_available():
            return self._engine
        # The accelerator this host resolves to, never the "cpu" default: this is also the
        # one-shot FALLBACK path (a GPU sd-server that would not start lands here), and asking
        # for the CPU build there would reinstall the plain bundle over the working GPU one and
        # run the whole generation on the CPU.
        binary = ensure_sd_cpp_binary(
            allow_install = _install_allowed() and not _tree_in_use(self),
            accelerator = self._resolved_accelerator(),
        )
        if not binary:
            raise RuntimeError("sd-cli (stable-diffusion.cpp) binary is unavailable.")
        self._engine = SdCppEngine(binary = binary)
        return self._engine

    def _resolve_backend(self) -> tuple[str, Optional[str], Optional[SdCppEngine]]:
        """Pick the native execution mode: ("server", binary, None) or ("oneshot", None, engine).

        The persistent ``sd-server`` is preferred (load once, serve many). The one-shot
        ``sd-cli`` is the fallback for older / custom builds that lack the server target.
        An explicitly injected engine forces one-shot (the unit-test seam and an escape
        hatch), so a test never spawns a real server or triggers an install. A lazily
        cached fallback engine does NOT force one-shot: once a resident server becomes
        available (installed, or a per-model start that previously failed now works), the
        next load can use it, instead of being pinned to one-shot for the whole session.
        """
        if self._engine_injected and self._engine is not None:
            return "oneshot", None, self._resolve_engine()
        accelerator = self._resolved_accelerator()
        # An accelerator upgrade REPLACES the binaries in the managed tree, and this runs before

View on GitHub (pinned to 203007d190)

Solutions

  1. Pre-install the managed binary (allow install once) or place a valid build where SD_CLI_PATH/UNSLOTH_SD_CPP_PATH points.
  2. Check backend logs for the underlying install failure (network, permissions, disk) and fix that.
  3. If a concurrent job holds the managed tree, let it finish and retry so the install is admitted.
  4. Confirm the binary passes the identity/H3 gate (see the --help checks) once present.
Defensive patterns

Strategy: try-catch

Try / catch

try:
    engine = backend._resolve_engine()
except RuntimeError as e:
    if 'binary is unavailable' in str(e):
        logger.error('sd-cli install failed or disallowed; pre-provision the binary')
    raise

Prevention

When it happens

Trigger: Calling generate/load on the native engine with install disallowed (policy/flag) and no binary present; the managed install failed (network/disk); a GPU sd-server would not start and the fallback also found no installable binary because the tree was in use.

Common situations: Air-gapped or restricted hosts where the managed download cannot run; read-only install prefixes; disk-full during managed install; concurrent operations holding the managed tree.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/376330a436c941e2. Report an issue: GitHub.