unslothai/unsloth · error · SttEngineUnavailableError

The local transcription runtime returned HTTP {response.stat

Error message

The local transcription runtime returned HTTP {response.status}.

What it means

SttEngineUnavailableError raised in the /inference POST handler: whisper-server answered but with a non-2xx status. The response body is not inspected; the status alone fails the request. 409 typically means the model is not (or no longer) loaded server-side; 5xx means the server choked on the payload.

Source

Thrown at studio/backend/core/inference/stt_ggml_sidecar.py:1191

            "127.0.0.1", self._port, timeout = _TRANSCRIBE_TIMEOUT_SECONDS
        )
        cancel_done = threading.Event()
        if cancel_event is not None:
            threading.Thread(
                target = _close_connection_on_cancel,
                args = (connection, cancel_event, cancel_done),
                daemon = True,
            ).start()
        try:
            connection.request(
                "POST",
                "/inference",
                body = body,
                headers = {"Content-Type": f"multipart/form-data; boundary={boundary}"},
            )
            with connection.getresponse() as response:
                if not 200 <= response.status < 300:
                    raise SttEngineUnavailableError(
                        f"The local transcription runtime returned HTTP {response.status}."
                    )
                payload = json.loads(response.read().decode("utf-8"))
        except (SttAudioDecodeError, SttEngineUnavailableError):
            raise
        except Exception as exc:
            # A cancel closes this socket deliberately, so it is not evidence of a broken
            # runtime and must not disable the engine.
            if cancel_event is None or not cancel_event.is_set():
                note_runtime_inference_failure(f"{type(exc).__name__}: {exc}")
            raise SttEngineUnavailableError(
                "The local transcription runtime did not answer the request. "
                "Transcription will use the Transformers engine from now on."
            ) from exc
        finally:
            cancel_done.set()
            connection.close()
        text = payload.get("text")

View on GitHub (pinned to 203007d190)

Solutions

  1. Retry once — a 409 after an idle unload usually resolves because transcribe() re-loads under the lock on the next call.
  2. Check that audio was encoded as 16 kHz mono WAV (_pcm_to_wav_bytes output) and within size caps.
  3. Run `unsloth studio update` to realign the managed whisper-server build.
  4. If 5xx persists, restart Studio so the sidecar respawns the child cleanly.
Defensive patterns

Strategy: retry

Try / catch

try:
    result = sidecar.transcribe(audio, language=lang)
except SttEngineUnavailableError as exc:
    if "returned HTTP 409" in str(exc) or "returned HTTP 5" in str(exc):
        result = sidecar.transcribe(audio, language=lang)  # reload under lock fixes 409
    else:
        raise

Prevention

When it happens

Trigger: Calling _post_inference with WAV bytes when the sidecar's model was unloaded/switched server-side (409), the WAV is malformed for whisper.cpp, or the server hit an internal error during transcription (5xx).

Common situations: Idle unload or model switch raced the inference POST; oversized/invalid audio payload; whisper-server version mismatch with the expected API; server in a degraded state after an earlier failure.

Related errors


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