BerriAI/litellm · error · ValueError
AZURE_SENTINEL_DCR_IMMUTABLE_ID is required. Set it as an en
Error message
AZURE_SENTINEL_DCR_IMMUTABLE_ID is required. Set it as an environment variable or pass dcr_immutable_id parameter.
What it means
The Azure Sentinel (Log Analytics DCR) logger requires a Data Collection Rule immutable ID to build its ingestion URL ({Endpoint}/dataCollectionRules/{DCR Immutable ID}/streams/...). At init it resolves dcr_immutable_id from the constructor parameter or AZURE_SENTINEL_DCR_IMMUTABLE_ID; if neither is present it raises ValueError. Unlike some Azure settings there is no generic AZURE_* fallback for this one — it is Sentinel-specific.
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 6c2dcb801b)
Solutions
- Get the DCR Immutable ID: az monitor data-collection rule show --name <rule> --resource-group <rg> --query immutableId
- Export it: AZURE_SENTINEL_DCR_IMMUTABLE_ID=<immutable-id> in the environment, or pass dcr_immutable_id=... when constructing the logger
- Also set the other required values (endpoint, tenant, client) since the same init raises for each of them in turn
- If running in Docker/K8s, add the variable to the container env spec and redeploy
Example fix
# before
AzureSentinelLogger() # ValueError: AZURE_SENTINEL_DCR_IMMUTABLE_ID is required
# after
AzureSentinelLogger(
dcr_immutable_id="dcr-0123456789abcdef0123456789abcdef",
endpoint="https://my-log-analytics-workspace-0dgb.eastus.ingest.monitor.azure.com",
tenant_id="<tenant-guid>",
client_id="<client-guid>",
client_secret="<secret>",
) Defensive patterns
Strategy: validation
Validate before calling
import os
REQUIRED_SENTINEL_VARS = (
"AZURE_SENTINEL_DCR_IMMUTABLE_ID",
"AZURE_SENTINEL_ENDPOINT",
"AZURE_SENTINEL_TENANT_ID",
"AZURE_SENTINEL_CLIENT_ID",
"AZURE_SENTINEL_CLIENT_SECRET",
)
missing = [v for v in REQUIRED_SENTINEL_VARS if not os.getenv(v)]
if missing:
raise RuntimeError(f"Missing Azure Sentinel config: {missing}") Type guard
def has_sentinel_config(env: dict) -> bool:
return all(env.get(v) for v in (
"AZURE_SENTINEL_DCR_IMMUTABLE_ID", "AZURE_SENTINEL_ENDPOINT",
"AZURE_SENTINEL_TENANT_ID", "AZURE_SENTINEL_CLIENT_ID", "AZURE_SENTINEL_CLIENT_SECRET",
)) Try / catch
try:
logger = AzureSentinelLogger()
except ValueError as e:
if "AZURE_SENTINEL_DCR_IMMUTABLE_ID" in str(e):
# config incomplete: disable callback or abort deploy; do not start half-configured
raise SystemExit(f"Azure Sentinel logger misconfigured: {e}") from e
raise Prevention
- Use a startup config check that validates all five Sentinel values at once
- Store the DCR immutable ID alongside the endpoint in the same secret store entry to keep them in sync
- Add the env block to container/K8s specs explicitly; never rely on host shell env
- Document that DCR immutable ID is the immutableId property, not the rule name
When it happens
Trigger: Enabling the azure_sentinel callback without setting AZURE_SENTINEL_DCR_IMMUTABLE_ID and without passing dcr_immutable_id=... to the constructor; typos in the env var name; env var set in a different shell/container than the one running litellm.
Common situations: Copying the Azure Sentinel docs example but skipping the DCR creation step; DCR created in Azure portal but its immutable ID (the full GUID-like immutableId property, not the rule name) never copied; secrets injected only into the proxy container and not the worker.
Related errors
- AZURE_SENTINEL_ENDPOINT is required. Set it as an environmen
- AZURE_SENTINEL_TENANT_ID or AZURE_TENANT_ID is required. Set
- AZURE_SENTINEL_CLIENT_ID or AZURE_CLIENT_ID is required. Set
- AZURE_SENTINEL_CLIENT_SECRET or AZURE_CLIENT_SECRET is requi
- Missing required environment variable: AZURE_STORAGE_ACCOUNT
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/8b02bbff100e006a.
Report an issue: GitHub.