Skip to content

[bug]: transport 502 echoes base_url including ?key= #423

Description

@Atharva-Kanherkar

symptom

switchyard-server 0.2.0 copies reqwest's transport error into the client 502. that string includes the full upstream url. if the admin put the provider key in base_url as ?key= (google's documented gemini shape), the caller gets the key.

header bearer keys and http userinfo (http://key@host) are not echoed. query params are.

reproduction

no server listening on 19998.

schema_version = 1
[llm_clients.local]
format = "openai_chat"
base_url = "http://127.0.0.1:19998/v1?key=CANARY_ADMIN_QUERY_KEY"
[llm_clients.local.extra_headers]
authorization = "Bearer CANARY_ADMIN_HEADER_KEY"
[targets.cap]
id = "captured-model"
llm_client = "local"
[routes.primary]
id = "captured-model"
type = "passthrough"
target = "cap"
switchyard-server --config sy.toml --port 9000
curl -s localhost:9000/v1/chat/completions \
  -H 'content-type: application/json' \
  -d '{"model":"captured-model","messages":[{"role":"user","content":"x"}],"max_tokens":8}'

actual: http 502. error.message is:

error sending request for url (http://127.0.0.1:19998/v1?key=CANARY_ADMIN_QUERY_KEY/chat/completions)

5/5. a 502 whose base_url has no query string does not contain the canary. a successful chat does not either. /health, /v1/models, /v1/stats stay clean.

expected vs. actual

  • expected: client-visible errors do not contain credentials from base_url.
  • actual: ?key= stays in the url string. the extra_headers bearer is not echoed.

environment

  • switchyard version (or commit sha): 0.2.0 (commit 2bef154)
  • python version (python --version): n/a (rust switchyard-server)
  • os / arch: macos arm64
  • install path: source build cargo build --release -p switchyard-server
  • inbound format (chat completions / anthropic messages / responses): chat completions, also stream and /v1/messages
  • backend (openai / anthropic / nvidia inference hub / other): closed local port (transport failure). live header-auth chats to openai/gemini/anthropic/openrouter did not echo the bearer.

additional context

client_error maps LlmClientError::Transport / Timeout to source.to_string(). reqwest includes the url. there is no redaction step. HttpBackendConfig's Debug impl redacts api_key, but that is not the path the client sees.

this is a canary-only report. no real provider keys in the public captures.

wire captures and replay tests: Atharva-Kanherkar/kairo#6

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions