BerriAI/litellm · error · HTTPException

Server misconfigured: master_key is not set

Error message

Server misconfigured: master_key is not set

What it means

HTTP 500 from the MCP bridge-envelope minting path: the proxy's master_key is unset, so the envelope encryption keys derived from it cannot exist. This is a server configuration problem (master_key env/config), not a caller error.

Source

Thrown at litellm/proxy/_experimental/mcp_server/auth/user_api_key_auth_mcp.py:783

        snapshot frozen at mint time. The inner upstream token is injected under the
        server's per-server auth-header key so egress forwards it via the
        ``PassthroughConfig`` override; the envelope ``Authorization`` the leak-defense
        strips never reaches the upstream. A new headers dict is returned rather than
        mutating the input. Fails closed with a 401 on an invalid or expired envelope, or
        when the referenced key is missing, blocked, or expired, its owner is
        SCIM-deactivated, or the centralized policy gate rejects it (blocked team or
        project, org or budget limits).

        The sealed token is keyed alias-first, matching the order egress resolves
        (``lookup_mcp_server_auth_in_headers`` tries ``alias`` before ``server_name``). Keying
        under ``server_name`` would leave a caller-supplied ``x-mcp-{alias}-authorization`` at the
        higher-priority alias slot, pairing the admitted identity with an attacker's upstream
        credential; the alias-keyed injection overwrites any such caller value.
        """
        from litellm.proxy.proxy_server import master_key

        if not master_key:
            raise HTTPException(status_code=500, detail="Server misconfigured: master_key is not set")

        await MCPRequestHandler._run_pre_db_read_auth_checks(request=request, route=route)

        keys: Final = envelope_keys_from_master_key(master_key)
        result: Final = resolve_bridge_envelope(authorization_value, keys, datetime.now(timezone.utc), server.server_id)
        match result:
            case BridgeEnvelopeAdmitted():
                header_key: Final = server.alias or server.server_name
                if header_key is None:
                    raise HTTPException(status_code=500, detail="Server misconfigured: MCP server has no routable name")
                admitted: Final = await MCPRequestHandler._reload_admitted_principal(result.identity)
                await MCPRequestHandler._enforce_admitted_live_policy(admitted=admitted, request=request, route=route)
                injected: Final = {header_key: {"Authorization": result.upstream_authorization.get_secret_value()}}
                new_headers: Final = {**(mcp_server_auth_headers or {}), **injected}
                return admitted, new_headers
            case BridgeEnvelopeInvalid() | NotBridgeEnvelope():
                raise HTTPException(status_code=401, detail="Invalid or expired credential")
            case _:

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Set the proxy master_key in config or LITELLM_MASTER_KEY env var.

Example fix

general_settings: {master_key: sk-...}
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at litellm/proxy/_experimental/mcp_server/auth/user_api_key_auth_mcp.py:783 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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