From f868c64c93b55afcc2cfdd13177560ff1e5b0771 Mon Sep 17 00:00:00 2001 From: PRABHU KIRAN VANDRANKI <72809214+VANDRANKI@users.noreply.github.com> Date: Tue, 9 Jun 2026 14:13:29 -0400 Subject: [PATCH] fix(router): strip Credential: tags before fallback deployment routing Fixes #25276 When a request fails and triggers fallback routing, the router's _add_model_to_request sets kwargs["metadata"]["tags"] to include a "Credential: " observability tag for the failed deployment. On the next retry, the same kwargs are reused, so that tag is visible to the tag-based access check for the fallback deployment. If the fallback deployment's model group doesn't allow the original "Credential: openai" tag, the fallback fails with a spurious 401: Not allowed to access model due to tags configuration. Passed model=gpt-image-1.5 and tags=['Credential: openai'] Fix: before appending the current deployment's Credential: tag, filter out any Credential: tags that were added by a prior deployment in this request's lifecycle. The new tag for the current deployment is still appended as before, so observability is unaffected for the successful delivery. --- litellm/router.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/litellm/router.py b/litellm/router.py index fac48b45fb3..aa178611e02 100644 --- a/litellm/router.py +++ b/litellm/router.py @@ -2735,8 +2735,14 @@ class Router: if credential_name: credential_tag = f"Credential: {credential_name}" existing_tags = kwargs[metadata_variable_name].get("tags") or [] - if credential_tag not in existing_tags: - existing_tags.append(credential_tag) + # Strip Credential: tags from any previous deployment attempt so they + # do not leak into fallback routing tag checks (fixes #25276). + existing_tags = [ + t + for t in existing_tags + if not (isinstance(t, str) and t.startswith("Credential: ")) + ] + existing_tags.append(credential_tag) kwargs[metadata_variable_name]["tags"] = existing_tags kwargs["model_info"] = model_info