Hmbown/CodeWhale · error

MCP server '{name}' already has bearer/static Authorization

Error message

MCP server '{name}' already has bearer/static Authorization configured

What it means

Before starting OAuth, the login path calls server_has_manual_authorization, which returns true when bearer_token_env_var is set or the headers/env_headers maps contain an Authorization header (oauth.rs:478, oauth.rs:583-587). Mixing a static credential with OAuth would create two competing Authorization sources, so the client refuses the login up front.

Source

Thrown at crates/tui/src/mcp/oauth.rs:478

    tokio::select! {
        biased;
        _ = cancellation_token.cancelled() => bail!("OAuth login was cancelled"),
        result = future => result,
    }
}

async fn perform_oauth_login_for_server_inner(
    name: &str,
    server: &McpServerConfig,
    explicit_scopes: Option<Vec<String>>,
    callback_port: Option<u16>,
    callback_url: Option<&str>,
) -> Result<()> {
    let Some(url) = server.url.as_deref() else {
        bail!("OAuth login is only supported for URL-based MCP servers");
    };
    if server_has_manual_authorization(server) {
        bail!("MCP server '{name}' already has bearer/static Authorization configured");
    }

    let discovery = if explicit_scopes.is_none() && server.scopes.is_empty() {
        oauth_login_support(server).await?
    } else {
        None
    };
    let resolved_scopes = resolve_oauth_scopes(
        explicit_scopes,
        server.scopes.clone(),
        discovery.and_then(|discovery| discovery.scopes_supported),
    );

    match perform_oauth_login(
        name,
        url,
        server.headers.clone(),
        server.env_headers.clone(),

View on GitHub (pinned to 0c42157ee5)

Solutions

  1. Remove bearer_token_env_var and any Authorization entry from the server's headers/env_headers, then re-run OAuth login
  2. Or keep the static credential and skip OAuth entirely — the server already has a working auth path
  3. If the Authorization header came from a plugin default, override it in your own config layer before logging in

Example fix

// before (config TOML)
[mcp.servers.my-server]
url = "https://mcp.example.com/mcp"
bearer_token_env_var = "MY_SERVER_TOKEN"

// after
[mcp.servers.my-server]
url = "https://mcp.example.com/mcp"
Defensive patterns

Strategy: validation

Validate before calling

let conflicts_manual_auth = server.bearer_token_env_var.is_some()
    || server.headers.keys().any(|k| k.eq_ignore_ascii_case("authorization"))
    || server.env_headers.keys().any(|k| k.eq_ignore_ascii_case("authorization"));
if conflicts_manual_auth {
    // pick one auth mode: clean the config, or skip OAuth
}

Type guard

fn has_manual_authorization(server: &McpServerConfig) -> bool {
    server.bearer_token_env_var.is_some()
        || server.headers.keys().any(|k| k.eq_ignore_ascii_case("authorization"))
        || server.env_headers.keys().any(|k| k.eq_ignore_ascii_case("authorization"))
}

Prevention

When it happens

Trigger: The McpServerConfig sets bearer_token_env_var, or has an `Authorization` entry in headers or env_headers, and the user invokes OAuth login for that server.

Common situations: A server migrated from static bearer auth to OAuth while the old bearer_token_env_var was left in config; a plugin or shared template injecting a default Authorization header; copy-pasted header blocks that include Authorization alongside plans to use OAuth.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20). Data as JSON: /api/errors/22748add444691bc. Report an issue: GitHub.