BerriAI/litellm · error · Exception

DD_SITE is not set, set 'DD_SITE=<>', example sit = `us5.dat

Error message

DD_SITE is not set, set 'DD_SITE=<>', example sit = `us5.datadoghq.com`

What it means

Companion check to 371: in direct-API mode (no LITELLM_DD_AGENT_HOST), DataDogLLMObsLogger also requires DD_SITE because it builds https://api.<site>/api/intake/llm-obs/v1/trace/spans. If DD_SITE is unset the constructor raises immediately with an example site in the message.

Source

Thrown at litellm/integrations/datadog/datadog_llm_obs.py:73

                create_mock_datadog_client()
                verbose_logger.debug("[DATADOG MOCK] DataDogLLMObs logger initialized in mock mode")

            # Configure DataDog endpoint (Agent or Direct API)
            # Use LITELLM_DD_AGENT_HOST to avoid conflicts with ddtrace's DD_AGENT_HOST
            # Check for agent mode FIRST - agent mode doesn't require DD_API_KEY or DD_SITE
            dd_agent_host: Final = os.getenv("LITELLM_DD_AGENT_HOST")

            self.async_client = get_async_httpx_client(llm_provider=httpxSpecialProvider.LoggingCallback)
            self.DD_API_KEY = os.getenv("DD_API_KEY")

            if dd_agent_host:
                self._configure_dd_agent(dd_agent_host=dd_agent_host)
            else:
                # Only require DD_API_KEY and DD_SITE for direct API mode
                if os.getenv("DD_API_KEY", None) is None:
                    raise Exception("DD_API_KEY is not set, set 'DD_API_KEY=<>'")
                if os.getenv("DD_SITE", None) is None:
                    raise Exception("DD_SITE is not set, set 'DD_SITE=<>', example sit = `us5.datadoghq.com`")
                self._configure_dd_direct_api()

            # Optional override for testing
            dd_base_url: Final = get_datadog_base_url_from_env()
            if dd_base_url:
                self.intake_url = f"{dd_base_url}/api/intake/llm-obs/v1/trace/spans"

            asyncio.create_task(self.periodic_flush())
            self.flush_lock = asyncio.Lock()
            self.log_queue: list[LLMObsPayload] = []

            #########################################################
            # Handle datadog_llm_observability_params set as litellm.datadog_llm_observability_params
            #########################################################
            dict_datadog_llm_obs_params: Final = self._get_datadog_llm_obs_params()
            kwargs.update(dict_datadog_llm_obs_params)
            CustomBatchLogger.__init__(self, **kwargs, flush_lock=self.flush_lock)
        except Exception as e:

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Export DD_SITE matching your org's site, e.g. us5.datadoghq.com or datadoghq.eu
  2. Or switch to agent mode with LITELLM_DD_AGENT_HOST to avoid direct-API credentials entirely
  3. Keep DD_API_KEY and DD_SITE in the same env/secret bundle so one is never set without the other

Example fix

# before
export DD_API_KEY=xxx
# DD_SITE unset -> raises

# after
export DD_API_KEY=xxx
export DD_SITE=us5.datadoghq.com
Defensive patterns

Strategy: validation

Validate before calling

import os

agent_mode = bool(os.getenv("LITELLM_DD_AGENT_HOST"))
if not agent_mode:
    assert os.getenv("DD_API_KEY"), "DD_API_KEY required for direct mode"
    assert os.getenv("DD_SITE"), "DD_SITE required for direct mode"

Try / catch

try:
    DataDogLLMObsLogger()
except Exception as e:
    if "DD_SITE" in str(e):
        export_and_restart("DD_SITE=us5.datadoghq.com")
    raise

Prevention

When it happens

Trigger: DataDogLLMObsLogger init with LITELLM_DD_AGENT_HOST unset, DD_API_KEY present, but DD_SITE absent from the environment.

Common situations: Teams that already export DD_API_KEY for logs but never needed DD_SITE before (other integrations defaulted it); new LLM-Obs enablement on existing Datadog setups.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/10fba62a9bd0dc2a. Report an issue: GitHub.