litellm/litellm
yucheng-berri 3fadcd7155
fix(auth): quiet malformed virtual key rejections to stdout (#38838)
* fix(auth): quiet malformed virtual key rejections to stdout

Reduce noisy invalid-api-key error logs by classifying malformed virtual
keys and routing their rejections to stdout as WARNING instead of stderr
as ERROR. Suppressible via LITELLM_LOG=ERROR or log_client_error_tracebacks=true.

Changes:
- auth_utils: is_invalid_virtual_key_error() classifier and marker functions
- auth_exception_handler: log invalid keys as WARNING to child logger before
  identity seeding and callbacks, escalate non-401 transforms to ERROR
- user_api_key_auth: websocket early-raise WebSocketException(1008) to avoid
  double-logging at HTTP layer
- _logging: child logger verbose_proxy_stdout_logger with no handler/level;
  LevelRoutingStreamHandler routes its WARNING records to stdout; handler
  setLevel in _turn_on_json() closes JSON config handler level leak
- test_auth_exception_handler: new test case verifying malformed-key logs
  at WARNING with marker retention through transformations

Fixes LIT-5362

* fix(auth): classify malformed-key 401 by raise-site marker, not message text

Review round 1 (Greptile P2, veria Low):
- Move the marker attribute name to litellm/constants.py per the shared
  sentinel convention
- Stamp the marker on the malformed-key 401 where it is raised and classify
  only by it. Message text is caller-influenceable on other 401s (vector
  store ids, organization ids are interpolated into their messages), so a
  phrase match would let a request body demote an authorization failure to
  the quiet log path
- Regression test: a 401 carrying the phrase but not the marker stays at
  ERROR on stderr
2026-08-31 18:19:40 -07:00
..
a2a_protocol Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_decrease_anys_opus5 2026-08-29 06:03:33 -07:00
anthropic_interface chore(lint): strip inert type: ignore comments and zero LIT009, LIT010, LIT011 headroom 2026-08-05 02:37:24 -07:00
assistants chore(lint): clear grandfathered over-limit lint drift and ratchet budgets down 2026-08-05 12:18:13 -07:00
batch_completion feat(lint): enforce Final on locals and freeze function parameters (LIT010, LIT011) 2026-08-04 12:54:39 -07:00
batches refactor(batches): make count_error_file_failed_requests public for the poller import 2026-08-29 14:09:18 -07:00
caching Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_decrease_anys_opus5 2026-08-29 06:03:33 -07:00
completion_extras fix(anthropic): carry tool_reference tool results through the guardrail translation round trip 2026-08-26 22:35:46 -07:00
compression chore(lint): strip inert type: ignore comments and zero LIT009, LIT010, LIT011 headroom 2026-08-05 02:37:24 -07:00
containers chore(typing): drop 1.3k basedpyright errors across 30 Any hotspot files 2026-08-16 03:56:02 +00:00
endpoints/speech/speech_to_completion_bridge refactor(speech): type the bridge voice param as a mapping and wrap a long test line 2026-08-29 15:26:05 -07:00
evals chore(typing): remove 914 basedpyright Any errors across 16 hotspot files 2026-08-10 01:24:40 -07:00
experimental_mcp_client feat(mcp): let a resolved OAuth token target a custom upstream header (#38456) 2026-08-27 14:32:01 -07:00
files fix(batches): accept litellm_proxy in files and batches provider type literals 2026-08-18 13:28:06 -07:00
fine_tuning Merge branch 'litellm_internal_staging' into litellm_remove_types_ruff_exclusion 2026-08-05 11:05:33 -07:00
google_genai chore(techdebt): drop restating comments from the 2026-08-30 window 2026-08-31 07:54:31 +00:00
images Merge origin/litellm_internal_staging into litellm_fix_36493_image_video_routes 2026-08-24 11:58:22 -07:00
integrations feat(shadow_eval): target teams and users so JWT-auth traffic can be evaluated (#39015) 2026-08-31 16:37:38 -07:00
interactions feat(vertex_ai): add native Vertex AI Interactions API support 2026-08-25 09:55:13 -07:00
litellm_core_utils Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_gigachat_passthrough_25886 2026-08-31 15:25:10 -07:00
llms Merge pull request #36008 from nuernber/litellm_bedrock_messages_disconnect_billing 2026-08-31 16:54:41 -07:00
models Merge pull request #38873 from BerriAI/litellm_fix_model_block_response_500 2026-08-31 15:56:21 -07:00
ocr fix(ocr): reject invalid req_format values as 400 on the SDK path 2026-08-17 15:49:18 -07:00
passthrough fix(passthrough): map sync streaming errors, keep router streaming responses unwrapped, and resolve gigachat from api base 2026-08-31 13:16:40 -07:00
proxy fix(auth): quiet malformed virtual key rejections to stdout (#38838) 2026-08-31 18:19:40 -07:00
proxy_auth feat(lint): enforce Final on locals and freeze function parameters (LIT010, LIT011) 2026-08-04 12:54:39 -07:00
rag chore(techdebt): clear fresh debt from the 2026-08-29 window 2026-08-30 07:57:16 +00:00
realtime_api fix(health): probe Azure GA realtime path for transcription-only models 2026-08-26 12:14:52 -07:00
repositories Merge branch 'litellm_internal_staging' into litellm_decrease_anys_opus5 2026-08-29 21:41:04 -07:00
rerank_api fix(together_ai): default endpoints to api.together.ai instead of api.together.xyz 2026-08-25 10:18:55 -07:00
responses fix(responses): count input_file tokens instead of silently dropping the file 2026-08-31 13:17:43 -07:00
router_strategy feat(complexity_router): escalate oversized prompts to a tier that fits before dispatch (#38844) 2026-08-31 16:12:59 -07:00
router_utils fix(router): arm the provider-scoped fallback pin only on resource-operating handlers 2026-08-29 01:46:33 -07:00
rust_bridge Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_decrease_anys_opus5 2026-08-29 06:03:33 -07:00
sandbox feat(lint): enforce Final on locals and freeze function parameters (LIT010, LIT011) 2026-08-04 12:54:39 -07:00
search chore(lint): strip inert type: ignore comments and zero LIT009, LIT010, LIT011 headroom 2026-08-05 02:37:24 -07:00
secret_managers Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_decrease_anys_opus5 2026-08-29 06:03:33 -07:00
skills chore(lint): strip inert type: ignore comments and zero LIT009, LIT010, LIT011 headroom 2026-08-05 02:37:24 -07:00
types feat(shadow_eval): target teams and users so JWT-auth traffic can be evaluated (#39015) 2026-08-31 16:37:38 -07:00
vector_store_files chore(lint): clear grandfathered over-limit lint drift and ratchet budgets down 2026-08-05 12:18:13 -07:00
vector_stores refactor(repositories): type prisma table access with one generic protocol 2026-08-25 12:14:17 +00:00
videos refactor(videos): make video upload param keyword-only on public edit fns 2026-08-24 15:55:07 -07:00
__init__.py fix(init): ignore pydantic ReadOnly TypedDict warning that floods proxy boot 2026-08-31 12:19:41 -07:00
_internal_context.py feat(lint): enforce Final on locals and freeze function parameters (LIT010, LIT011) 2026-08-04 12:54:39 -07:00
_lazy_imports.py Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_decrease_anys_opus5 2026-08-29 06:37:10 -07:00
_lazy_imports_registry.py fix(together_ai): route chat completions through a dedicated TogetherAIChatConfig 2026-08-25 11:44:06 -07:00
_logging.py fix(auth): quiet malformed virtual key rejections to stdout (#38838) 2026-08-31 18:19:40 -07:00
_redis.py refactor(redis): drop docstrings restating the code 2026-08-26 10:45:56 -07:00
_redis_credential_provider.py chore(lint): strip inert type: ignore comments and zero LIT009, LIT010, LIT011 headroom 2026-08-05 02:37:24 -07:00
_service_logger.py chore(lint): clear grandfathered over-limit lint drift and ratchet budgets down 2026-08-05 12:18:13 -07:00
_uuid.py chore(lint): strip inert type: ignore comments and zero LIT009, LIT010, LIT011 headroom 2026-08-05 02:37:24 -07:00
_version.py
anthropic_beta_headers_config.json
anthropic_beta_headers_manager.py feat(lint): enforce Final on locals and freeze function parameters (LIT010, LIT011) 2026-08-04 12:54:39 -07:00
blog_posts.json
budget_manager.py feat(lint): enforce Final on locals and freeze function parameters (LIT010, LIT011) 2026-08-04 12:54:39 -07:00
constants.py fix(auth): quiet malformed virtual key rejections to stdout (#38838) 2026-08-31 18:19:40 -07:00
cost.json
cost_calculator.py fix(cost_calculator): scope region_name to response-derived model names 2026-08-28 12:19:14 -07:00
exceptions.py feat(proxy): redact or drop individual batch records instead of rejecting the file (#37561) 2026-08-20 13:12:55 -07:00
main.py Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_gigachat_passthrough_25886 2026-08-29 22:08:54 -07:00
model_prices_and_context_window_backup.json Merge pull request #38913 from BerriAI/litellm_gigachat_passthrough_25886 2026-08-31 15:47:27 -07:00
policy_templates_backup.json
provider_endpoints_support_backup.json feat(hosted_vllm): add vLLM-Omni videos API 2026-08-24 17:10:44 -04:00
py.typed
router.py Merge pull request #38913 from BerriAI/litellm_gigachat_passthrough_25886 2026-08-31 15:47:27 -07:00
scheduler.py feat(lint): enforce Final on locals and freeze function parameters (LIT010, LIT011) 2026-08-04 12:54:39 -07:00
setup_wizard.py chore(lint): strip inert type: ignore comments and zero LIT009, LIT010, LIT011 headroom 2026-08-05 02:37:24 -07:00
timeout.py feat(lint): enforce Final on locals and freeze function parameters (LIT010, LIT011) 2026-08-04 12:54:39 -07:00
utils.py Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_gigachat_passthrough_25886 2026-08-29 22:08:54 -07:00