{"record":{"id":"9385c7205eba6ba8","repo":"BerriAI/litellm","slug":"auth-error-9385c7","errorCode":"auth_error","errorMessage":"Authentication Error, {e}","messagePattern":"Authentication Error, (.+?)","errorType":"http","errorClass":"ProxyException","httpStatus":500,"severity":"error","filePath":"litellm/proxy/health_endpoints/_health_endpoints.py","lineNumber":486,"sourceCode":"\n            return {\n                \"status\": \"success\",\n                \"message\": \"Mock Email Alert sent, verify Email Alert Received\",\n            }\n\n    except Exception as e:\n        verbose_proxy_logger.error(\"litellm.proxy.proxy_server.health_services_endpoint(): Exception occured - %s\", e)\n        verbose_proxy_logger.debug(traceback.format_exc())\n        if isinstance(e, HTTPException):\n            raise ProxyException(\n                message=getattr(e, \"detail\", f\"Authentication Error({e})\"),\n                type=ProxyErrorTypes.auth_error,\n                param=getattr(e, \"param\", \"None\"),\n                code=getattr(e, \"status_code\", status.HTTP_500_INTERNAL_SERVER_ERROR),\n            )\n        elif isinstance(e, ProxyException):\n            raise e\n        raise ProxyException(\n            message=\"Authentication Error, \" + str(e),\n            type=ProxyErrorTypes.auth_error,\n            param=getattr(e, \"param\", \"None\"),\n            code=status.HTTP_500_INTERNAL_SERVER_ERROR,\n        )\n\n\ndef _convert_health_check_to_dict(check) -> dict:\n    \"\"\"Convert health check database record to dictionary format\"\"\"\n    return {\n        \"health_check_id\": check.health_check_id,\n        \"model_name\": check.model_name,\n        \"model_id\": check.model_id,\n        \"status\": check.status,\n        \"healthy_count\": check.healthy_count,\n        \"unhealthy_count\": check.unhealthy_count,\n        \"error_message\": check.error_message,\n        \"response_time_ms\": check.response_time_ms,","sourceCodeStart":468,"sourceCodeEnd":504,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/proxy/health_endpoints/_health_endpoints.py#L468-L504","documentation":"The /health/services endpoint sends test alerts (Slack, email) for configured integrations. Its catch-all converts any exception into a ProxyException typed auth_error; exceptions that are neither HTTPException nor ProxyException get the generic 'Authentication Error, {e}' message with code 500. Despite the label, it usually means the integration test itself failed, not that your proxy virtual key is invalid.","triggerScenarios":"Calling GET /health/services?service=slack when Slack alerting is not configured in general_settings (the resulting 422 'not in proxy config' HTTPException is itself wrapped by this handler), or when the Slack webhook send fails; testing service=email without TEST_EMAIL_ADDRESS set.","commonSituations":"Operator tests alerting before adding the alerting config; SLACK_WEBHOOK_URL secret missing or the webhook revoked; SMTP/email settings incomplete; env var TEST_EMAIL_ADDRESS unset for email tests.","solutions":["Configure alerting under general_settings (alerting: ['slack'], alert_types, webhook_url secret) before testing","Verify the Slack webhook is live by posting to it directly with curl","Set TEST_EMAIL_ADDRESS when testing the email service","Read the wrapped detail - it carries the original exception text from the alerting handler, which names the real failure"],"exampleFix":"# before: testing with no alerting configured\n# GET /health/services?service=slack  -> 500 Authentication Error\n\n# after: config.yaml\ngeneral_settings:\n  alerting: ['slack']\n  alert_types:\n    - llm_exceptions\n    - db_exceptions\nlitellm_settings:\n  callbacks: ['litellm.proxy.litellm_proxy_hooks.slack_alerting.slack_alerting']","handlingStrategy":"try-catch","validationCode":"# Only test alerting services that are actually configured\nimport httpx\n\ncfg = yaml.safe_load(open('config.yaml'))\nalerting = (cfg.get('general_settings') or {}).get('alerting') or []\nif 'slack' in alerting:\n    httpx.get('http://localhost:4000/health/services', params={'service': 'slack'}, headers={'Authorization': f'Bearer {ADMIN_KEY}'})\nelse:\n    print('alerting not configured - skip the test')","typeGuard":null,"tryCatchPattern":"from litellm.proxy._types import ProxyException\n\ntry:\n    r = admin_client.get('/health/services', params={'service': 'slack'})\n    r.raise_for_status()\nexcept ProxyException as e:\n    # detail carries the alerting-handler failure; 'Authentication Error' label is generic\n    log.error('alert test failed: %s', e.message)","preventionTips":["Configure and verify alerting (webhook URL, alert_types) before wiring /health/services into runbooks","Curl the Slack webhook directly when tests fail to isolate litellm vs Slack","Set TEST_EMAIL_ADDRESS in the proxy environment when email alerting is used"],"tags":["alerting","slack","webhook","health","proxy-exception"],"backgroundTag":"webhook-delivery-failed","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}