astrid-runtime/astrid · error
expected MCP attach registration
Error message
expected MCP attach registration
What it means
read_registration_inner reads one line-delimited JSON gateway request from an attach client and requires it to be a GatewayRequest::Attach registration. If the client sends a Control request instead (or any non-Attach variant), the gateway rejects it because the very first preface on an attach connection must be a registration.
Source
Thrown at crates/astrid-cli/src/commands/mcp/gateway.rs:867
result.map(|_| ())
}
async fn read_registration<R>(reader: &mut BufReader<R>) -> Result<AttachRegistration>
where
R: AsyncRead + Unpin,
{
timeout(REGISTRATION_TIMEOUT, read_registration_inner(reader))
.await
.context("timed out reading MCP attach registration")?
}
async fn read_registration_inner<R>(reader: &mut BufReader<R>) -> Result<AttachRegistration>
where
R: AsyncRead + Unpin,
{
match read_gateway_request_inner(reader).await? {
GatewayRequest::Attach(registration) => Ok(registration),
GatewayRequest::Control(_) => anyhow::bail!("expected MCP attach registration"),
}
}
async fn read_gateway_request<R>(reader: &mut BufReader<R>) -> Result<GatewayRequest>
where
R: AsyncRead + Unpin,
{
timeout(REGISTRATION_TIMEOUT, read_gateway_request_inner(reader))
.await
.context("timed out reading MCP gateway registration")?
}
async fn read_gateway_request_inner<R>(reader: &mut BufReader<R>) -> Result<GatewayRequest>
where
R: AsyncRead + Unpin,
{
let mut line = Vec::new();
let mut terminated = false;View on GitHub (pinned to affd8760f4)
Solutions
- Ensure the attach client sends a JSON GatewayRequest::Attach registration as the first line after connecting to the attach socket.
- Send control operations (stop/status) over the gateway control channel, not the per-attach registration preface.
- Check the client's ATTACH_REGISTRATION_VERSION and message shape match the current protocol version.
- If writing a custom client, model it on the existing attach implementation: single-line JSON, correct variant, within 16 KiB and REGISTRATION_TIMEOUT.
Example fix
// before: control preface on attach socket
{"type":"control","version":1,...}
// after: attach registration preface
{"type":"attach","version":1,"host":"...","host_session_id":"...","principal":"...","hook_token":"..."} Defensive patterns
Strategy: validation
Validate before calling
fn is_attach_preface(first_line: &[u8]) -> bool {
serde_json::from_slice::<serde_json::Value>(first_line)
.ok()
.and_then(|v| v.get("type").cloned())
.map_or(false, |t| t == "attach")
} Type guard
fn is_attach(req: &GatewayRequest) -> bool {
matches!(req, GatewayRequest::Attach(_))
} Try / catch
match result {
Err(e) if e.to_string().contains("expected MCP attach registration") => eprintln!("attach socket requires an Attach preface first"),
other => other?,
} Prevention
- Always send the Attach registration as the first line on the attach socket.
- Use the control channel for control operations, never the attach preface.
- Share one protocol-definition module between client and gateway.
- Test the first-line payload shape before deploying custom clients.
When it happens
Trigger: An attach client sends a GatewayRequest::Control message as its first preface over the Unix socket; read_registration (used at connection setup and by oversized_registration_preface_fails_without_waiting_for_a_newline) encounters the Control variant.
Common situations: A client implementation or script speaks the control protocol (stop/status) over the attach socket instead of the dedicated control path; protocol mix-ups where a reconnect sends the wrong preface; a corrupted or misrouted connection.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- MCP attach registration is missing or too large
- unsupported MCP gateway control version {}
- MCP gateway attach limit reached for principal '{principal}'
- {primary:#}; additional gateway cleanup failure: {secondary:
- MCP gateway control authority is incomplete
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/727ead9b89726ba1.
Report an issue: GitHub.