openai/codex · error
Invalid MCP server name '{server_name}': must match pattern
Error message
Invalid MCP server name '{server_name}': must match pattern {pattern} What it means
Before connecting, validate_mcp_server_name (called from start) checks the MCP server key against ^[a-zA-Z0-9_-]+$. Server names become tool namespaces, config keys and cache identifiers, so anything outside ASCII letters, digits, underscore and hyphen (spaces, dots, slashes, colons, unicode) is rejected at startup with the offending name and the exact pattern.
Source
Thrown at codex-rs/codex-mcp/src/rmcp_client.rs:861
"Environment variable {env_var} for MCP server '{server_name}' is empty"
))
} else {
Ok(Some(value))
}
}
Err(env::VarError::NotPresent) => Err(anyhow!(
"Environment variable {env_var} for MCP server '{server_name}' is not set"
)),
Err(env::VarError::NotUnicode(_)) => Err(anyhow!(
"Environment variable {env_var} for MCP server '{server_name}' contains invalid Unicode"
)),
}
}
fn validate_mcp_server_name(server_name: &str) -> Result<()> {
let re = regex_lite::Regex::new(r"^[a-zA-Z0-9_-]+$")?;
if !re.is_match(server_name) {
return Err(anyhow!(
"Invalid MCP server name '{server_name}': must match pattern {pattern}",
pattern = re.as_str()
));
}
Ok(())
}
#[instrument(level = "trace", skip_all, fields(server_name = %server_name))]
async fn start_server_task(
server_name: String,
client: Arc<RmcpClient>,
params: StartServerTaskParams,
) -> Result<ManagedClient, StartupOutcomeError> {
let StartServerTaskParams {
is_codex_apps_mcp_server,
startup_timeout,
tx_event,
elicitation_requests,View on GitHub (pinned to 339751715c)
Solutions
- Rename the key to only [A-Za-z0-9_-], e.g. [mcp_servers.github_proxy] instead of [mcp_servers."github proxy"]
- Check the key for invisible leading/trailing whitespace or a BOM
- If the name is generated, slugify it before registering: replace separators with '-' and strip non-ASCII
Example fix
# before [mcp_servers."github proxy"] url = "https://mcp.github.com/api" # after [mcp_servers.github_proxy] url = "https://mcp.github.com/api"
Defensive patterns
Strategy: validation
Validate before calling
// Validate before registering or writing config
fn is_valid_mcp_server_name(name: &str) -> bool {
!name.is_empty()
&& name.bytes().all(|b| b.is_ascii_alphanumeric() || b == b'_' || b == b'-')
} Type guard
pub fn is_valid_mcp_server_name(name: &str) -> bool {
regex_lite::Regex::new(r"^[a-zA-Z0-9_-]+$").unwrap().is_match(name)
} Prevention
- Use slug-style ids everywhere a server is named: config keys, registrations, generated entries
- Add a config lint that rejects keys outside [A-Za-z0-9_-]
- Never paste human display names into [mcp_servers.*] keys
When it happens
Trigger: config.toml keys like [mcp_servers."my server"], [mcp_servers.github/api], [mcp_servers."db.prod"] or unicode names; keys with leading/trailing whitespace from copy-paste; programmatically registered servers (app-server MCP APIs) whose ids were never slugified.
Common situations: Display names pasted as TOML keys; generated names containing '/', ':' or non-ASCII; renaming a server to a human-friendly label in config.
Related errors
- Environment variable {env_var} for MCP server '{server_name}
- executor-owned MCP server `{server_name}` cannot use hosted
- MCP server '{server}' is not registered by the hosted runtim
- invalid requirement for MCP server `{server_name}` (set by {
- config defines `[permissions]` profiles but does not set `de
AI-assisted analysis of openai/codex@339751715c (2026-08-25).
Data as JSON: /api/errors/ccb809fb05453279.
Report an issue: GitHub.