[BUG] rust-analyzer-lsp plugin crashes with exit code 1 — Claude Code sends malformed byte before LSP Content-Length header

Resolved 💬 1 comment Opened May 12, 2026 by Detective-XH Closed Jun 11, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

The rust-analyzer-lsp plugin crashes immediately on startup with exit code 1, and /doctor reports:

LSP server plugin:rust-analyzer-lsp:rust-analyzer crashed with exit code 1
LSP server 'plugin:rust-analyzer-lsp:rust-analyzer' exceeded max crash recovery attempts (3)

Root cause: Claude Code sends a malformed byte (\n) as the first byte to rust-analyzer's stdin before the LSP Content-Length header. rust-analyzer's header parser is strict and exits with:

Error: malformed header: "\n"

The binary itself is healthy — sending a valid Content-Length header works correctly (see Steps to Reproduce). The bug is in how Claude Code initialises the LSP stdin pipe.

What Should Happen?

Claude Code should start rust-analyzer in LSP server mode without sending any bytes before the Content-Length header. rust-analyzer should respond with its capabilities and remain running as the language server for .rs files.

Error Messages/Logs

Error: malformed header: "\n"
     3: std::sys::backtrace::__rust_begin_short_backtrace::<<stdx::thread::Builder>::spawn<rust_analyzer::
  run_server, core::result::Result<(), anyhow::Error>>::{closure#0}, core::result::Result<(),
  anyhow::Error>>
     4: <std::thread::lifecycle::spawn_unchecked<<stdx::thread::Builder>::spawn<rust_analyzer::run_server,
   core::result::Result<(), anyhow::Error>>::{closure#0}, core::result::Result<(),
  anyhow::Error>>::{closure#1} as core::ops::function::FnOnce<()>>::call_once::{shim:vtable#0}
     5: <std::sys::thread::unix::Thread>::new::thread_start
     6: __pthread_cond_wait
  exit: 1

Steps to Reproduce

  1. Install rust-analyzer via rustup:

rustup component add rust-analyzer

  1. Verify rust-analyzer is working:

rust-analyzer --version
# → rust-analyzer 1.95.0 (59807616 2026-04-14)

  1. Install the LSP plugin:

/plugin install rust-analyzer-lsp@claude-plugins-official

  1. Open Claude Code in any directory containing .rs files.
  1. Run /doctor — observe the crash report:

LSP server plugin:rust-analyzer-lsp:rust-analyzer crashed with exit code 1
LSP server exceeded max crash recovery attempts (3)

--- Confirming the root cause ---

  1. Reproduce the crash manually (simulates what Claude Code sends):

{ echo ''; sleep 1; } | rust-analyzer
# → Error: malformed header: "\n", exit 1

  1. Confirm rust-analyzer works with a valid LSP message:

MSG='{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"processId":null,"rootUri":"file:///path/to/project","capabilities":{}}}'
LEN=${#MSG}
printf "Content-Length: %d\r\n\r\n%s" "$LEN" "$MSG" | rust-analyzer
# → Responds with full capabilities JSON, no errors

The contrast between steps 6 and 7 confirms Claude Code is sending a bare \n before the Content-Length header.

--- Workaround (active) ---
Created ~/.local/bin/rust-analyzer (PATH position 1) as a proxy that strips any bytes before Content-Length:, then forwards to ~/.cargo/bin/rust-analyzer. This eliminates the crash.

Claude Model

Sonnet (default)

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.139

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

_No response_

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗