BerriAI/litellm · error · ValueError

callback_name is required in key_logging

Error message

callback_name is required in key_logging

What it means

Raised while preparing the per-key logging-callback health probe: every entry in the key's 'logging' metadata list must be a dict containing 'callback_name'; an entry without it cannot be mapped to a configured callback, so a ValueError aborts the check. It is raised inside the health-check try block, so the client actually receives it wrapped as 'Key health check failed: callback_name is required in key_logging' with status 500.

Source

Thrown at litellm/proxy/management_endpoints/key_management_endpoints.py:6548

    """
    Test the key-based logging

    - Test that key logging is correctly formatted and all args are passed correctly
    - Make a mock completion call -> user can check if it's correctly logged
    - Check if any logger.exceptions were triggered -> if they were then returns it to the user client side
    """
    import logging
    from io import StringIO

    from litellm.proxy.litellm_pre_call_utils import add_litellm_data_to_request
    from litellm.proxy.proxy_server import general_settings, proxy_config

    logging_callbacks: Final[list[str]] = []
    for callback in key_logging:
        if callback.get("callback_name") is not None:
            logging_callbacks.append(callback["callback_name"])
        else:
            raise ValueError("callback_name is required in key_logging")

    log_capture_string: Final = StringIO()
    ch: Final = logging.StreamHandler(log_capture_string)
    ch.setLevel(logging.ERROR)
    logger: Final = logging.getLogger()
    logger.addHandler(ch)

    try:
        data = {
            "model": "openai/litellm-key-health-test",
            "messages": [
                {
                    "role": "user",
                    "content": "Hello, this is a test from litellm /key/health. No LLM API call was made for this",
                }
            ],
        }
        data = await add_litellm_data_to_request(

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Ensure every element of metadata['logging'] includes 'callback_name', e.g. {"callback_name": "litellm.proxy.custom_callbacks.my_handler.MyHandler"}
  2. Verify the named callback actually appears in proxy_logging_obj's loaded callbacks — otherwise fix config.yaml callback_settings/litellm_settings first
  3. Update the key's metadata via /key/update rather than recreating the key
  4. Re-run GET /key/health after fixing; the 500 wrapper disappears once the inner ValueError is gone

Example fix

# before
await client.post('/key/generate', json={
    'metadata': {'logging': [{'class': 'my_pkg.MyLogger'}]}   # -> 500 Key health check failed: callback_name is required in key_logging
})
# after
await client.post('/key/generate', json={
    'metadata': {'logging': [{'callback_name': 'my_pkg.MyLogger'}]}
})
Defensive patterns

Strategy: validation

Validate before calling

def validate_key_logging(logging_entries: list) -> None:
    for i, entry in enumerate(logging_entries):
        if not isinstance(entry, dict) or not entry.get('callback_name'):
            raise ValueError(f"logging[{i}] is missing required 'callback_name'")

Type guard

def is_valid_key_logging(entries: object) -> bool:
    return (
        isinstance(entries, list)
        and all(isinstance(e, dict) and isinstance(e.get('callback_name'), str) and e['callback_name'] for e in entries)
    )

Try / catch

try:
    await client.post('/key/generate', json=payload_with_logging_metadata)
except httpx.HTTPStatusError as e:
    if 'callback_name is required' in e.response.text:
        raise ValueError('fix metadata.logging entries: each needs callback_name') from e
    raise

Prevention

When it happens

Trigger: Setting key metadata like {"logging": [{"class": "my_pkg.MyLogger"}]} or [{"callback_type": "logger"}] with no callback_name; hand-editing metadata JSON and dropping the field; older docs/examples that used a different key name for the callback.

Common situations: Custom callback integrations added via key metadata; migration from older LiteLLM metadata conventions; programmatic metadata assembly that conditionally omits the name.

Understand the failure class

Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.

Related errors


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