BerriAI/litellm · error · LassoGuardrailMissingSecrets

Invalid API key

Error message

Invalid API key

What it means

Raised as LassoGuardrailMissingSecrets when the Lasso API responds with HTTP 401, i.e. the lasso-api-key header sent by the guardrail was rejected. Despite the class name (chosen because litellm maps it to a missing/invalid-secret condition), it means authentication failed — the key is wrong, revoked, or from another workspace — not necessarily that it is absent (a fully absent key is caught earlier in _prepare_headers).

Solutions

  1. Regenerate the key in the Lasso dashboard and update LASSO_API_KEY in the environment of the process running litellm proxy, then restart it.
  2. Print/verify the exact key the running process sees (e.g. printenv LASSO_API_KEY inside the container) to catch truncation, quotes, or trailing whitespace.
  3. Confirm the key belongs to the same Lasso workspace/environment as the API endpoint the guardrail calls.
  4. If you pass lasso_api_key via config.yaml, make sure the os.environ/LASSO_API_KEY reference resolves at proxy startup.

Example fix

# before (.env — truncated/typo'd key)
LASSO_API_KEY=lasso_sk_abc123...

# after
LASSO_API_KEY=lasso_sk_full_valid_key_from_lasso_dashboard
Defensive patterns

Strategy: validation

Validate before calling

# Startup: fail fast if the key is absent before the first guarded request
import os

def validate_lasso_key() -> None:
    key = os.environ.get("LASSO_API_KEY")
    assert key, "LASSO_API_KEY is not set — set it before enabling the lasso guardrail"
    assert not key.strip() != key, "LASSO_API_KEY has leading/trailing whitespace"
    assert len(key) > 20, "LASSO_API_KEY looks truncated"

Type guard

from litellm.proxy.guardrails.guardrail_hooks.lasso.lasso import LassoGuardrailMissingSecrets

def is_invalid_lasso_key(err: Exception) -> bool:
    """True when Lasso rejected the key (401) — not a transient failure."""
    return isinstance(err, LassoGuardrailMissingSecrets) and "Invalid API key" in str(err)

Try / catch

from litellm.proxy.guardrails.guardrail_hooks.lasso.lasso import LassoGuardrailMissingSecrets

try:
    result = await guardrail_hook(data)
except LassoGuardrailMissingSecrets as e:
    # Credential problem: NEVER retry; page the operator and fail closed
    if "Invalid API key" in str(e):
        raise RuntimeError("Lasso rejected LASSO_API_KEY — rotate the key") from e
    raise

Prevention

When it happens

Trigger: A guarded request reaches _prepare_headers with a non-empty key (from LASSO_API_KEY or lasso_api_key in config), the lasso-api-key header is sent to the Lasso API, and Lasso returns status 401, which httpx surfaces as HTTPStatusError and this handler maps to LassoGuardrailMissingSecrets('Invalid API key').

Common situations: Typo'd or truncated LASSO_API_KEY value (often from a .env file with quotes/whitespace or a line-wrap); the key was rotated or revoked in the Lasso dashboard but the proxy still runs the old one; using a key from a different Lasso workspace/environment (staging vs prod); the env var was set in a different shell than the one launching litellm.

Understand the failure class

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/1c1b7aab8c361ed3. Report an issue: GitHub.

Appendix: source

Thrown at litellm/proxy/guardrails/guardrail_hooks/lasso/lasso.py:614

        # Log error with context
        verbose_proxy_logger.error(
            "Error calling Lasso API: %s",
            error,
            extra={
                "guardrail_name": getattr(self, "guardrail_name", "unknown"),
                "message_type": message_type,
                "error_type": type(error).__name__,
            },
        )

        # Handle specific error types if httpx is available
        if HTTPX_AVAILABLE:
            if isinstance(error, httpx.TimeoutException):
                raise LassoGuardrailAPIError("Lasso API timeout")
            elif isinstance(error, httpx.HTTPStatusError):
                if error.response.status_code == 401:
                    raise LassoGuardrailMissingSecrets("Invalid API key")
                elif error.response.status_code == 429:
                    raise LassoGuardrailAPIError("Lasso API rate limit exceeded")
                else:
                    raise LassoGuardrailAPIError(f"API error: {error.response.status_code}")

        # Generic error handling
        raise LassoGuardrailAPIError(f"Failed to verify request safety with Lasso API: {error}")

    def _log_masking_applied(
        self,
        message_type: Literal["PROMPT", "COMPLETION"],
        response: dict[str, Any],
    ) -> None:
        """Log masking application with structured context."""
        conversation_id: Final = getattr(self, "conversation_id", "unknown")
        verbose_proxy_logger.debug(
            "Lasso masking applied",
            extra={

View on GitHub (pinned to 77b7c6c40c)