go-delve/delve · error
qThreadStopInfo mismatch, requested %s got %s
Error message
qThreadStopInfo mismatch, requested %s got %s
What it means
Thrown in the qThreadStopInfo handling when Delve waits (with a 10ms read deadline) for the stop packet for a specific thread and the read times out — no packet arrived in time, so Delve reports that the requested thread ID did not match what it got (nothing). This happens while racing to pick up which thread actually stopped after a continue.
Source
Thrown at pkg/proc/gdbserial/gdbserver_conn.go:1165
}
if sp.threadID != threadID {
// When we send a ^C (manual stop request) and the process is close to
// stopping anyway, sometimes, debugserver will send back two stop
// packets. We need to ignore this spurious stop packet. Because the first
// thing we do after the stop is updateThreadList, which calls this
// function, this is relatively painless. We simply need to check that the
// stop packet we receive is for the thread we requested, if it isn't we
// can assume it is the spurious extra stop packet and simply ignore it.
// An example of a problematic interaction is in the commit message for
// this change.
// See https://github.com/go-delve/delve/issues/3013.
conn.conn.SetReadDeadline(time.Now().Add(10 * time.Millisecond))
resp, err = conn.recv(conn.outbuf.Bytes(), "thread stop info", false)
conn.conn.SetReadDeadline(time.Time{})
if err != nil {
if neterr, isneterr := err.(net.Error); isneterr && neterr.Timeout() {
return stopPacket{}, fmt.Errorf("qThreadStopInfo mismatch, requested %s got %s", sp.threadID, threadID)
}
return stopPacket{}, err
}
_, sp, err = conn.parseStopPacket(resp, "", nil)
if err != nil {
return stopPacket{}, err
}
if sp.threadID != threadID {
return stopPacket{}, fmt.Errorf("qThreadStopInfo mismatch, requested %s got %s", sp.threadID, threadID)
}
}
return sp, nil
}
// restart executes a 'vRun' command.
func (conn *gdbConn) restart(pos string) error {
conn.outbuf.Reset()View on GitHub (pinned to a23773e6c3)
Solutions
- Retry the operation — it is a timing race and often succeeds on retry
- Reduce target/system latency (wired connection instead of network/Wi-Fi, close background load)
- Upgrade Delve; timeout handling in qThreadStopInfo has been adjusted in newer versions
- If consistently reproducible, capture gdbwire logs and file an issue with the stub details
Defensive patterns
Strategy: retry
Try / catch
sp, err := conn.waitForSpecificStop(threadID)
if err != nil && strings.Contains(err.Error(), "qThreadStopInfo mismatch") {
select {
case <-time.After(50 * time.Millisecond):
return conn.waitForSpecificStop(threadID) // bounded retry
}
} Prevention
- Minimize latency to the target (wired links, local gdbserver)
- Avoid overloading the host during remote debugging sessions
- Upgrade Delve for improved timeout windows in qThreadStopInfo handling
- Treat this error as transient: implement bounded retries in tooling
When it happens
Trigger: After a stop, Delve queries per-thread stop info for threadID; conn.recv times out at the 10ms deadline (net.Error Timeout), and the code converts the timeout into this mismatch error with an empty sp.threadID.
Common situations: Slow or loaded remote targets (network gdbserver, device debugging) where the stub takes longer than 10ms to answer; USB serial latency on iOS debugging; high system load delaying the reply.
Related errors
- wrong response length, expected %d got %d
- malformed response for vCont %s
- malformed stop packet: %s
- malformed stop packet: %s (wrong watch address)
- malformed stop packet: %s (wrong jstopinfo)
AI-assisted analysis of go-delve/delve@a23773e6c3 (2026-08-31).
Data as JSON: /api/errors/6c3204d3e552999d.
Report an issue: GitHub.