{"record":{"id":"ca1614d9939d3ed8","repo":"AdguardTeam/AdGuardHome","slug":"another-client-q-uses-the-same-ip-q","errorCode":null,"errorMessage":"another client %q uses the same IP %q","messagePattern":"another client %q uses the same IP %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/index.go","lineNumber":123,"sourceCode":"// clashes returns an error if the index contains a different persistent client\n// with at least a single identifier contained by c.  c must be non-nil.\nfunc (ci *index) clashes(c *Persistent) (err error) {\n\tif p := ci.clashesName(c); p != nil {\n\t\treturn fmt.Errorf(\"another client uses the same name %q\", p.Name)\n\t}\n\n\tfor _, id := range c.ClientIDs {\n\t\texisting, ok := ci.clientIDToUID[id]\n\t\tif ok && existing != c.UID {\n\t\t\tp := ci.uidToClient[existing]\n\n\t\t\treturn fmt.Errorf(\"another client %q uses the same ClientID %q\", p.Name, id)\n\t\t}\n\t}\n\n\tp, ip := ci.clashesIP(c)\n\tif p != nil {\n\t\treturn fmt.Errorf(\"another client %q uses the same IP %q\", p.Name, ip)\n\t}\n\n\tp, s := ci.clashesSubnet(c)\n\tif p != nil {\n\t\treturn fmt.Errorf(\"another client %q uses the same subnet %q\", p.Name, s)\n\t}\n\n\tp, mac := ci.clashesMAC(c)\n\tif p != nil {\n\t\treturn fmt.Errorf(\"another client %q uses the same MAC %q\", p.Name, mac)\n\t}\n\n\treturn nil\n}\n\n// clashesName returns existing persistent client with the same name as c or\n// nil.  c must be non-nil.\nfunc (ci *index) clashesName(c *Persistent) (existing *Persistent) {","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/client/index.go#L105-L141","documentation":"Thrown when a new or updated client's IP address collides with another client's IP in the storage index. Each persistent client must have a unique IP. The error reports the existing client's name and the clashing IP.","triggerScenarios":"Calling Storage.Add or Storage.Update with a client whose IP (or whose IP is matched by clashesIP) equals the IP of a different already-stored client.","commonSituations":"Static-IP client lists where two devices were assigned the same address, DHCP reservations duplicated across clients, importing YAML configs with copy-pasted IP fields.","solutions":["Find the client named in the message and change one of the two IPs to a free address","If the same device is being re-added, use Update on the existing client by name instead of Add","Validate IPs for uniqueness before loading InitialClients into NewStorage"],"exampleFix":"// before\nclient.IP = \"192.168.1.10\" // already used by \"printer\"\ns.Add(ctx, client)\n\n// after\nclient.IP = \"192.168.1.42\"\ns.Add(ctx, client)","handlingStrategy":"validation","validationCode":"for _, p := range existing {\n    if p.UID != c.UID && p.IP == c.IP { /* clash */ }\n}","typeGuard":null,"tryCatchPattern":"if err := s.Add(ctx, c); err != nil && strings.Contains(err.Error(), \"uses the same IP\") { /* reassign IP or Update */ }","preventionTips":["Allocate client IPs from a managed pool","Deduplicate IPs when generating InitialClients"],"tags":["client","ip","duplicate","validation"],"backgroundTag":"duplicate-identifier-conflict","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}