BerriAI/litellm · error · ValueError

Invalid mode

Error message

Invalid mode: {custom_auth_settings['mode']}

What it means

Raised as a ValueError by enterprise_custom_auth when custom_auth_settings is non-null but its 'mode' key is not one of the three supported values ('on', 'off', 'auto'). The mode controls how the custom auth callable interacts with LiteLLM's built-in auth: 'on' always runs it, 'off' skips it, 'auto' falls back to LiteLLM auth on non-ProxyException errors. Any other string aborts auth setup with this error.

Solutions

  1. Set the mode to exactly 'on', 'off', or 'auto' (lowercase) in custom_auth_settings
  2. Remove custom_auth_settings entirely if you want the default behavior (handler always called)
  3. Validate the config against the documented schema before deploy (litellm proxy config check)

Example fix

# before
custom_auth_settings:
  mode: enabled   # -> ValueError: Invalid mode: enabled
# after
custom_auth_settings:
  mode: auto      # fall back to LiteLLM auth on handler errors
Defensive patterns

Strategy: validation

Validate before calling

VALID_MODES = {"on", "off", "auto"}
assert custom_auth_settings is None or custom_auth_settings["mode"] in VALID_MODES, (
    f"custom_auth_settings.mode must be one of {sorted(VALID_MODES)}")

Type guard

def is_valid_auth_mode(settings: dict | None) -> bool:
    return settings is None or settings.get("mode") in {"on", "off", "auto"}

Try / catch

try:
    await enterprise_custom_auth(request, api_key)
except ValueError as e:
    if str(e).startswith("Invalid mode:"):
        # fail closed: reject request, alert on config error
        raise HTTPException(status_code=500, detail="auth config error")
    raise

Prevention

When it happens

Trigger: Defining custom_auth_settings in the enterprise proxy config with a typo'd or unsupported mode value such as 'true', 'enabled', 'always', or 'ON' (matching is case-sensitive lowercase); passing a mode key the enterprise build added in a later version than the one deployed.

Common situations: Hand-written config yaml with custom_auth_settings: {mode: enabled}; upgrading/downgrading the enterprise package where the accepted mode vocabulary changed; config generated by templating that injects a boolean instead of a string.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at enterprise/litellm_enterprise/proxy/auth/user_api_key_auth.py:35

    if custom_auth_settings is None:
        return await user_custom_auth(request, api_key)

    if custom_auth_settings["mode"] == "on":
        return await user_custom_auth(request, api_key)
    elif custom_auth_settings["mode"] == "off":
        return None
    elif custom_auth_settings["mode"] == "auto":
        try:
            return await user_custom_auth(request, api_key)
        except ProxyException as e:
            raise e
        except Exception as e:
            verbose_proxy_logger.debug(
                f"Error in custom auth, checking litellm auth: {e}"
            )
            return None
    else:
        raise ValueError(f"Invalid mode: {custom_auth_settings['mode']}")

View on GitHub (pinned to 77b7c6c40c)