astrid-runtime/astrid · error
MCP attach registration is missing or too large
Error message
MCP attach registration is missing or too large
What it means
read_gateway_request_inner reads the registration preface byte-by-byte up to MAX_REGISTRATION_BYTES (16 KiB) awaiting a newline. If the stream ends or the size ceiling is hit before a terminating newline arrives, the gateway bails with 'missing or too large' — covering both truncated prefaces and oversized/DoS-y registrations.
Source
Thrown at crates/astrid-cli/src/commands/mcp/gateway.rs:898
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;
for _ in 0..=MAX_REGISTRATION_BYTES {
let byte = reader
.read_u8()
.await
.context("failed to read MCP attach registration")?;
if byte == b'\n' {
terminated = true;
break;
}
line.push(byte);
}
if !terminated {
anyhow::bail!("MCP attach registration is missing or too large");
}
let request: GatewayRequest =
serde_json::from_slice(&line).context("MCP gateway registration is not valid JSON")?;
match &request {
GatewayRequest::Control(control) => {
if control.version != GATEWAY_CONTROL_VERSION {
anyhow::bail!(
"unsupported MCP gateway control version {}",
control.version
);
}
if control.pid == 0 || control.hook_token.trim().is_empty() {
anyhow::bail!("MCP gateway control authority is incomplete");
}
},
GatewayRequest::Attach(registration) => validate_registration(registration)?,
}
Ok(request)View on GitHub (pinned to affd8760f4)
Solutions
- Terminate the registration JSON with a single newline ('\n') after the last byte.
- Keep the entire registration preface under 16 KiB; move large data (tokens, env) out of the registration.
- Write the preface promptly after connect — the gateway enforces REGISTRATION_TIMEOUT (5s) and half-open sockets are dropped.
- If you legitimately need more preface data, that ceiling (MAX_REGISTRATION_BYTES) is a protocol constant and requires a code change on both ends.
Example fix
// before stream.write_all(json_bytes).await?; // after let mut preface = json_bytes.to_vec(); preface.push(b'\n'); stream.write_all(&preface).await?;
Defensive patterns
Strategy: validation
Validate before calling
fn preface_ok(json: &str) -> bool {
json.len() <= 16 * 1024 && !json.contains('\n')
} Try / catch
match result {
Err(e) if e.to_string().contains("missing or too large") => eprintln!("registration preface must be a newline-terminated line < 16 KiB"),
other => other?,
} Prevention
- Always append a trailing newline after the registration JSON.
- Keep the preface minimal; do not embed large tokens or blobs.
- Write the preface immediately after connect to beat REGISTRATION_TIMEOUT.
- Set a client-side write timeout so partial writes are detected.
When it happens
Trigger: An attach client sends a registration line longer than 16 KiB, sends bytes without ever writing '\n' before EOF, or stalls so REGISTRATION_TIMEOUT expires leaving a non-terminated buffer.
Common situations: A hand-rolled client forgets the trailing newline after the JSON preface; a client embeds huge credentials/blobs into the registration; a broken/half-open socket delivers a partial line; a malicious or buggy scanner hits the listener.
Understand the failure class
Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.
Related errors
- expected MCP attach registration
- 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/28571e3fee42b19a.
Report an issue: GitHub.