BerriAI/litellm · error · ValueError
AZURE_SENTINEL_DCR_IMMUTABLE_ID is required. Set it as an…
Error message
AZURE_SENTINEL_DCR_IMMUTABLE_ID is required. Set it as an environment variable or pass dcr_immutable_id parameter.
What it means
AzureSentinelLogger.__init__ resolves the Data Collection Rule immutable id from the dcr_immutable_id constructor kwarg or the AZURE_SENTINEL_DCR_IMMUTABLE_ID env var; if neither is set it raises immediately, before any log can be shipped. The DCR immutable id is the immutableId GUID of the Azure Monitor Data Collection Rule that tells the Logs Ingestion API how to route records into the target table.
Solutions
- Retrieve the value with `az monitor data-collection rule show --name <dcr> --resource-group <rg> --query immutableId` (or portal: Data Collection Rule -> JSON view -> immutableId) and export AZURE_SENTINEL_DCR_IMMUTABLE_ID=<that guid>
- Or pass dcr_immutable_id="..." explicitly when constructing AzureSentinelLogger programmatically
- Set the other four required values at the same time (endpoint, tenant id, client id, client secret) — each has its own check that will fire next
- Redeploy the proxy/worker so the new env is visible to the process
Example fix
// before export AZURE_SENTINEL_ENDPOINT=https://my-ws-o1.ingest.monitor.azure.com export AZURE_SENTINEL_TENANT_ID=... # DCR id forgotten -> ValueError at init // after export AZURE_SENTINEL_DCR_IMMUTABLE_ID="dcr-0000aaaa1111bbbb2222cccc3333dddd" export AZURE_SENTINEL_ENDPOINT=https://my-ws-o1.ingest.monitor.azure.com export AZURE_SENTINEL_TENANT_ID=... export AZURE_SENTINEL_CLIENT_ID=... export AZURE_SENTINEL_CLIENT_SECRET=...
Defensive patterns
Strategy: validation
Validate before calling
import os
required = {
"dcr_immutable_id": ("AZURE_SENTINEL_DCR_IMMUTABLE_ID",),
"endpoint": ("AZURE_SENTINEL_ENDPOINT",),
"tenant_id": ("AZURE_SENTINEL_TENANT_ID", "AZURE_TENANT_ID"),
"client_id": ("AZURE_SENTINEL_CLIENT_ID", "AZURE_CLIENT_ID"),
"client_secret": ("AZURE_SENTINEL_CLIENT_SECRET", "AZURE_CLIENT_SECRET"),
}
missing = [n for n, envs in required.items() if not any(os.getenv(e) for e in envs)]
if missing:
raise RuntimeError(f"azure_sentinel not configured, missing: {missing}") Prevention
- Provision DCR + association + app registration before enabling the callback
- Store all five values in one secret/env file so they are set or unset as a unit
- Add a startup smoke test that constructs AzureSentinelLogger before serving traffic
- Capture immutableId programmatically (az monitor data-collection rule show --query immutableId) rather than copying from the portal
When it happens
Trigger: Adding "azure_sentinel" to litellm callbacks/settings without provisioning the Azure Monitor pipeline; creating the DCR in the portal but never copying its immutableId; exporting the other AZURE_SENTINEL_* values but not this one; running the proxy in a pod whose secret mount omitted this key.
Common situations: Teams note the DCR resource name instead of its immutableId; CI/staging environments missing secrets; docs examples that show only endpoint and tenant; rotating to a new DCR without updating env.
Understand the failure class
Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.
Related errors
- AZURE_SENTINEL_ENDPOINT is required. Set it as an…
- AZURE_SENTINEL_CLIENT_ID or AZURE_CLIENT_ID is required…
- AZURE_SENTINEL_CLIENT_SECRET or AZURE_CLIENT_SECRET is…
- AZURE_SENTINEL_TENANT_ID or AZURE_TENANT_ID is required…
- Missing required environment variable…
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/8b02bbff100e006a.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/integrations/azure_sentinel/azure_sentinel.py:105
resolved_stream_name: Final = stream_name or os.getenv("AZURE_SENTINEL_STREAM_NAME") or "Custom-LiteLLM"
resolved_audit_stream_name: Final = (
audit_stream_name or os.getenv("AZURE_SENTINEL_AUDIT_STREAM_NAME") or resolved_stream_name
)
resolved_endpoint: Final = endpoint or os.getenv("AZURE_SENTINEL_ENDPOINT")
resolved_tenant_id: Final = tenant_id or os.getenv("AZURE_SENTINEL_TENANT_ID") or os.getenv("AZURE_TENANT_ID")
resolved_client_id: Final = client_id or os.getenv("AZURE_SENTINEL_CLIENT_ID") or os.getenv("AZURE_CLIENT_ID")
resolved_client_secret: Final = (
client_secret or os.getenv("AZURE_SENTINEL_CLIENT_SECRET") or os.getenv("AZURE_CLIENT_SECRET")
)
resolved_authority_host: Final = self._normalize_authority_host(
authority_host
or os.getenv("AZURE_SENTINEL_AUTHORITY_HOST")
or os.getenv("AZURE_AUTHORITY_HOST")
or DEFAULT_AZURE_AUTHORITY_HOST
)
if not resolved_dcr_immutable_id:
raise ValueError(
"AZURE_SENTINEL_DCR_IMMUTABLE_ID is required. Set it as an environment variable or pass dcr_immutable_id parameter."
)
if not resolved_endpoint:
raise ValueError(
"AZURE_SENTINEL_ENDPOINT is required. Set it as an environment variable or pass endpoint parameter."
)
if not resolved_tenant_id:
raise ValueError(
"AZURE_SENTINEL_TENANT_ID or AZURE_TENANT_ID is required. Set it as an environment variable or pass tenant_id parameter."
)
if not resolved_client_id:
raise ValueError(
"AZURE_SENTINEL_CLIENT_ID or AZURE_CLIENT_ID is required. Set it as an environment variable or pass client_id parameter."
)
if not resolved_client_secret:
raise ValueError(
"AZURE_SENTINEL_CLIENT_SECRET or AZURE_CLIENT_SECRET is required. Set it as an environment variable or pass client_secret parameter."
)View on GitHub (pinned to 77b7c6c40c)