{"record":{"id":"10e6ee014206d78a","repo":"gastownhall/beads","slug":"authenticated-proxy-identity-does-not-match-its-pi","errorCode":null,"errorMessage":"authenticated proxy identity does not match its pidfile or workspace","messagePattern":"authenticated proxy identity does not match its pidfile or workspace","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/dbproxy/proxy/endpoint.go","lineNumber":631,"sourceCode":"\treply, err := identity.Identify(\"127.0.0.1\", pf.ControlPort, secret, identityProbeTimeout)\n\tif err != nil {\n\t\treturn adoptionResult{status: adoptionIdentityMismatch, pidfile: pf, err: err}\n\t}\n\t// Accept schema v2 or newer, matching pidfile.ValidateV2's forward-compat\n\t// policy for records.\n\tif reply.Schema < pidfile.SchemaV2 ||\n\t\treply.Role != pidfile.KindProxy ||\n\t\treply.RootID != expectedRootID ||\n\t\treply.RootID != pf.RootID ||\n\t\treply.PID != pf.Pid ||\n\t\treply.Birth != pf.Birth ||\n\t\treply.DataPort != pf.Port ||\n\t\treply.ControlPort != pf.ControlPort ||\n\t\treply.UpstreamID != pf.UpstreamID {\n\t\treturn adoptionResult{\n\t\t\tstatus:  adoptionIdentityMismatch,\n\t\t\tpidfile: pf,\n\t\t\terr:     errors.New(\"authenticated proxy identity does not match its pidfile or workspace\"),\n\t\t}\n\t}\n\n\tep := Endpoint{Host: \"127.0.0.1\", Port: pf.Port}\n\tif !probePort(ep, identityProbeTimeout) {\n\t\treturn adoptionResult{\n\t\t\tstatus:  adoptionIdentityMismatch,\n\t\t\tpidfile: pf,\n\t\t\terr:     fmt.Errorf(\"authenticated proxy data port %d is not accepting connections\", pf.Port),\n\t\t}\n\t}\n\treturn adoptionResult{status: adoptionAdopted, endpoint: ep, pidfile: pf}\n}\n\nfunc probePort(ep Endpoint, timeout time.Duration) bool {\n\tconn, err := net.DialTimeout(\"tcp\", ep.Address(), timeout)\n\tif err != nil {\n\t\treturn false","sourceCodeStart":613,"sourceCodeEnd":649,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/storage/dbproxy/proxy/endpoint.go#L613-L649","documentation":"This error is returned by readAndDial when the freshly spawned/authenticated proxy's handshake reply does not match the pidfile or workspace (mismatched PID, data/control port, or UpstreamID). It indicates the process that answered is not the proxy this workspace owns, so adoption is refused and the record is quarantined.","triggerScenarios":"readAndDial adoption probe where reply.PID, DataPort, ControlPort, or UpstreamID differs from the pidfile values; a foreign listener answering on the expected port.","commonSituations":"Another process grabbed the port between spawn and handshake; PID reuse; two workspaces/instances sharing a port range; stale pidfile pointing at someone else's server.","solutions":["Let the library quarantine the record (default behavior) and retry the start to get a clean spawn on a fresh port","Check for port collisions with other workspaces or leftover processes (lsof/ss) and kill/avoid them","Ensure only one beads instance manages the workspace at a time (use the stop-epoch/lock protocol)"],"exampleFix":"// before\nres := readAndDial(rootDir, pf)\n// caller assumes success\n// after\nres := readAndDial(rootDir, pf)\nif res.status == adoptionIdentityMismatch {\n    // library already quarantined the foreign record; restart cleanly\n    return spawnFreshProxy(rootDir)\n}","handlingStrategy":"type-guard","validationCode":"// before adopting, verify the listener identity\nif !pidMatchesPidfile(reply.PID, pf) || reply.UpstreamID != pf.UpstreamID { return errForeignListener }","typeGuard":"func isIdentityMismatch(status adoptionStatus) bool { return status == adoptionIdentityMismatch }","tryCatchPattern":"res := readAndDial(rootDir, pf)\nif res.status == adoptionIdentityMismatch {\n    // record already quarantined; start a clean proxy\n    return spawnFreshProxy(rootDir)\n}","preventionTips":["Ensure one workspace owner at a time","Avoid overlapping port allocations between instances","Clean stale pidfiles before start"],"tags":["identity","security","pidfile","handshake"],"backgroundTag":"identity-mismatch","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}