HKUDS/Vibe-Trading · error · ValueError

MCP servers using auth must not also set static headers (the

Error message

MCP servers using auth must not also set static headers (the OAuth provider owns the Authorization header)

What it means

Raised by validate_transport_config when an HTTP server defines both an auth block and static headers. The OAuth provider injects the Authorization header at runtime, so a hand-set static header would conflict with or shadow it — the schema treats this as always a config error.

Source

Thrown at agent/src/config/schema.py:404

        if transport == "stdio":
            if not self.command.strip():
                raise ValueError("stdio MCP servers require a command")
            if self.url.strip() or self.headers:
                raise ValueError("stdio MCP servers do not accept url/headers")
            if self.auth is not None:
                raise ValueError("stdio MCP servers do not accept auth (OAuth is HTTP-only)")
            return self

        if not self.url.strip():
            raise ValueError(f"{transport} MCP servers require a url")
        if self.command.strip() or self.args or self.env:
            raise ValueError(f"{transport} MCP servers do not accept command/args/env")

        if self.auth is not None:
            # The OAuth provider owns the runtime Authorization header; a
            # hand-set static header alongside it is always a config error.
            if self.headers:
                raise ValueError(
                    "MCP servers using auth must not also set static headers "
                    "(the OAuth provider owns the Authorization header)"
                )
            # A refresh token must never traverse cleartext.
            if not self.url.strip().lower().startswith("https://"):
                raise ValueError("OAuth MCP servers require an https url")
        return self


class MCPServerConfigOverride(ConfigBase):
    """Partial MCP server override used for runtime config layering."""

    type: Literal["stdio", "sse", "streamableHttp"] | None = None
    command: str | None = None
    args: list[str] | None = None
    env: dict[str, str] | None = None
    url: str | None = None
    headers: dict[str, str] | None = None

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Delete the headers block and let the OAuth provider manage Authorization.
  2. If static headers were for a proxy or custom API key (not OAuth), remove auth and keep only headers.

Example fix

# before
mcp_servers:
  broker:
    type: streamableHttp
    url: https://api.example.com/mcp
    auth: {client_id: abc}
    headers: {Authorization: "Bearer x"}

# after
mcp_servers:
  broker:
    type: streamableHttp
    url: https://api.example.com/mcp
    auth: {client_id: abc}
Defensive patterns

Strategy: validation

Validate before calling

def auth_headers_exclusive(entry: dict) -> bool:
    if entry.get('auth') is not None:
        return not entry.get('headers')
    return True

Prevention

When it happens

Trigger: An entry with auth set (e.g. OAuth client) plus a headers: {Authorization: ...} or any static headers mapping.

Common situations: Migrating from static API-key headers to OAuth and leaving old headers in place; copy-pasted examples that include both auth styles.

Understand the failure class

Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/0137037dd5db63fb. Report an issue: GitHub.