{"record":{"id":"28571e3fee42b19a","repo":"astrid-runtime/astrid","slug":"mcp-attach-registration-is-missing-or-too-large","errorCode":null,"errorMessage":"MCP attach registration is missing or too large","messagePattern":"MCP attach registration is missing or too large","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/mcp/gateway.rs","lineNumber":898,"sourceCode":"async fn read_gateway_request_inner<R>(reader: &mut BufReader<R>) -> Result<GatewayRequest>\nwhere\n    R: AsyncRead + Unpin,\n{\n    let mut line = Vec::new();\n    let mut terminated = false;\n    for _ in 0..=MAX_REGISTRATION_BYTES {\n        let byte = reader\n            .read_u8()\n            .await\n            .context(\"failed to read MCP attach registration\")?;\n        if byte == b'\\n' {\n            terminated = true;\n            break;\n        }\n        line.push(byte);\n    }\n    if !terminated {\n        anyhow::bail!(\"MCP attach registration is missing or too large\");\n    }\n    let request: GatewayRequest =\n        serde_json::from_slice(&line).context(\"MCP gateway registration is not valid JSON\")?;\n    match &request {\n        GatewayRequest::Control(control) => {\n            if control.version != GATEWAY_CONTROL_VERSION {\n                anyhow::bail!(\n                    \"unsupported MCP gateway control version {}\",\n                    control.version\n                );\n            }\n            if control.pid == 0 || control.hook_token.trim().is_empty() {\n                anyhow::bail!(\"MCP gateway control authority is incomplete\");\n            }\n        },\n        GatewayRequest::Attach(registration) => validate_registration(registration)?,\n    }\n    Ok(request)","sourceCodeStart":880,"sourceCodeEnd":916,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/mcp/gateway.rs#L880-L916","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nstream.write_all(json_bytes).await?;\n// after\nlet mut preface = json_bytes.to_vec();\npreface.push(b'\\n');\nstream.write_all(&preface).await?;","handlingStrategy":"validation","validationCode":"fn preface_ok(json: &str) -> bool {\n    json.len() <= 16 * 1024 && !json.contains('\\n')\n}","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"missing or too large\") => eprintln!(\"registration preface must be a newline-terminated line < 16 KiB\"),\n    other => other?,\n}","preventionTips":["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."],"tags":["mcp","protocol","gateway","payload-too-large"],"backgroundTag":"payload-too-large","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}