BerriAI/litellm · error · Exception
Missing keys= in environment.
Error message
Missing keys={missing_keys} in environment. What it means
OpenMeterLogger.validate_environment() runs in the callback's __init__ and raises a generic Exception when OPENMETER_API_KEY is absent from the environment. Despite the docstring mentioning OPENMETER_API_ENDPOINT too, only the API key is actually enforced — the endpoint falls back to https://openmeter.cloud. Because this fires at logger construction, adding 'openmeter' to your callbacks list without the env var crashes callback initialization (startup or first import of the callback).
Solutions
- Set the API key: export OPENMETER_API_KEY=<your OpenMeter API key>
- Optionally set the endpoint if not using OpenMeter Cloud: export OPENMETER_API_ENDPOINT=https://<your-endpoint> (the code appends /api/v1/events, so provide the base URL only)
- Confirm the variable is visible to the process that constructs the callback (printenv OPENMETER_API_KEY inside the container/runtime)
- Restart/redeploy the proxy or re-import the SDK so the callback reconstructs and validation passes
Example fix
# before litellm_settings: callbacks: ["openmeter"] # env: nothing set -> Exception at startup # after litellm_settings: callbacks: ["openmeter"] # env: # OPENMETER_API_KEY=<key> # OPENMETER_API_ENDPOINT=https://openmeter.cloud # optional
Defensive patterns
Strategy: validation
Validate before calling
import os
if not os.getenv('OPENMETER_API_KEY'):
raise SystemExit('OPENMETER_API_KEY is required when the openmeter callback is enabled')
# optional: sanity-check a custom endpoint base URL
endpoint = os.getenv('OPENMETER_API_ENDPOINT', 'https://openmeter.cloud')
assert endpoint.startswith('http'), 'OPENMETER_API_ENDPOINT must be a base http(s) URL' Try / catch
try:
from litellm.integrations.openmeter import OpenMeterLogger
cb = OpenMeterLogger() # validate_environment runs here
except Exception as e:
raise RuntimeError(f'OpenMeter callback misconfigured: {e}') from e Prevention
- Gate callback registration on presence of OPENMETER_API_KEY in your bootstrap code
- Remember only the API key is validated — the endpoint silently defaults to openmeter.cloud, so set it explicitly for self-hosted
- Store OpenMeter credentials in the same secret backend the deployment mounts
- Smoke-test one metered call after enabling the callback and confirm events arrive in OpenMeter
When it happens
Trigger: Adding openmeter to litellm_callbacks / litellm_settings.callbacks in config.yaml (or litellm.callbacks = ['openmeter'] in SDK usage) in a process where OPENMETER_API_KEY is unset. The error message formats the missing key(s) as a Python list, e.g. Missing keys=['OPENMETER_API_KEY'] in environment.
Common situations: Enabling OpenMeter cost logging after reading the docs but only setting the endpoint var; env var set in a local .env that the deployed container never loads; OPENMETER_API_KEY defined in a CI secrets mask but not exported; rotating keys and accidentally deleting the variable; expecting the endpoint to be required too and misreading which var failed.
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
- Either 'REDIS_URL' or both 'REDIS_HOST' and 'REDIS_PORT'…
- LEVOAI_ORG_ID environment variable is required for Levo…
- LEVOAI_WORKSPACE_ID environment variable is required for…
- Missing JWT Public Key URL from environment.
- Block Code Execution guardrail requires a guardrail_name
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/4f911ab131487ed8.
Report an issue: GitHub.
Appendix: source
Thrown at litellm/integrations/openmeter.py:49
super().__init__()
self.validate_environment()
self.async_http_handler = get_async_httpx_client(llm_provider=httpxSpecialProvider.LoggingCallback)
self.sync_http_handler = HTTPHandler()
def validate_environment(self):
"""
Expects
OPENMETER_API_ENDPOINT,
OPENMETER_API_KEY,
in the environment
"""
missing_keys: Final = []
if os.getenv("OPENMETER_API_KEY", None) is None:
missing_keys.append("OPENMETER_API_KEY")
if len(missing_keys) > 0:
raise Exception(f"Missing keys={missing_keys} in environment.")
def _common_logic(self, kwargs: dict, response_obj):
call_id: Final = response_obj.get("id", kwargs.get("litellm_call_id"))
dt: Final = get_utc_datetime().isoformat()
cost: Final = kwargs.get("response_cost", None)
model: Final = kwargs.get("model")
usage = {}
if (
isinstance(response_obj, litellm.ModelResponse) or isinstance(response_obj, litellm.EmbeddingResponse)
) and hasattr(response_obj, "usage"):
usage = {
"prompt_tokens": response_obj["usage"].get("prompt_tokens", 0),
"completion_tokens": response_obj["usage"].get("completion_tokens", 0),
"total_tokens": response_obj["usage"].get("total_tokens"),
}
# OPENMETER_TRUST_REQUEST_USER (default "true"): when set to "false",
# the request-supplied `user` field is ignored and the subject isView on GitHub (pinned to 77b7c6c40c)