gastownhall/beads · error
identity: oversized reply
Error message
identity: oversized reply
What it means
Identify reads a single newline-delimited JSON reply from the control connection and enforces a hard cap of maxIdentReplyBytes (4096). A reply longer than the cap is rejected outright — the peer is not speaking the identity protocol or is hostile, so no attempt is made to parse it.
Source
Thrown at internal/storage/dbproxy/identity/control.go:69
}
nonceBytes := make([]byte, identNonceBytes)
if _, err := rand.Read(nonceBytes); err != nil {
return nil, fmt.Errorf("identity: generate request nonce: %w", err)
}
nonce := hex.EncodeToString(nonceBytes)
if _, err := io.WriteString(conn, "IDENT "+secret+" "+nonce+"\n"); err != nil {
return nil, fmt.Errorf("identity: write request: %w", err)
}
line, err := bufio.NewReader(io.LimitReader(conn, maxIdentReplyBytes+1)).ReadString('\n')
if errors.Is(err, io.EOF) && len(line) == 0 {
return nil, ErrIdentRefused
}
if err != nil {
return nil, fmt.Errorf("identity: read reply: %w", err)
}
if len(line) > maxIdentReplyBytes {
return nil, errors.New("identity: oversized reply")
}
var reply IdentReply
if err := json.Unmarshal([]byte(line), &reply); err != nil {
return nil, fmt.Errorf("identity: decode reply: %w", err)
}
if err := VerifyIdentReply(reply, secret, nonce); err != nil {
return nil, err
}
return &reply, nil
}
// SignIdentReply authenticates reply for the nonce in an IDENT request.
// The MAC covers the raw nonce bytes followed by canonical JSON for every
// reply field except MAC.
func SignIdentReply(reply IdentReply, secret, nonce string) (IdentReply, error) {
nonceBytes, err := decodeIdentNonce(nonce)
if err != nil {View on GitHub (pinned to 71377f2769)
Solutions
- Confirm the socket belongs to the managed proxy and speaks the identity protocol (correct version/schema)
- Reject and re-dial; do not retry against the same peer without verifying its identity first
- Cap reads client-side as well so a hostile peer cannot exhaust memory before this check
- Audit who can connect to the control socket (filesystem permissions on the unix socket)
Example fix
// before
reply, err := identity.Identify(conn, secret)
if err != nil { log.Fatal(err) }
// after
reply, err := identity.Identify(conn, secret)
if err != nil {
if strings.Contains(err.Error(), "oversized reply") { return ErrNotAProxyPeer } // wrong/hostile listener
return err
} Defensive patterns
Strategy: validation
Validate before calling
// client-side cap: never read unbounded from the control socket limited := io.LimitReader(conn, identity.MaxIdentReplyBytes+1)
Type guard
func isOversizedReply(err error) bool { return strings.Contains(err.Error(), "oversized reply") } Try / catch
if err != nil {
if isOversizedReply(err) { conn.Close(); return ErrUntrustedPeer } // drop connection
return err
} Prevention
- Point identity discovery only at the managed proxy's control socket
- Restrict unix-socket permissions to the service user
- Never retry Identify against a peer that sent oversized garbage
- Keep protocol versions aligned between beads and the proxy
When it happens
Trigger: Calling Identify against a listener that answers the identity request with data exceeding 4096 bytes before the first newline — e.g. a misconfigured service, garbage/binary response, or an unauthenticated peer flooding the socket.
Common situations: Pointing identity discovery at the wrong socket (a different daemon that replies verbosely); a compromised or rogue process squatting on the control socket; protocol version mismatch producing large error payloads.
Related errors
- identity: invalid reply MAC
- identity: request refused
- identity: reply authentication failed
- ErrMissingBirth
- authenticated proxy identity does not match its pidfile or w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/ea43267688d0dd2f.
Report an issue: GitHub.