{"record":{"id":"ac36c02a262e2edd","repo":"AdguardTeam/AdGuardHome","slug":"another-client-q-uses-the-same-mac-q","errorCode":null,"errorMessage":"another client %q uses the same MAC %q","messagePattern":"another client %q uses the same MAC %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/client/index.go","lineNumber":133,"sourceCode":"\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) {\n\texisting, ok := ci.findByName(c.Name)\n\tif !ok {\n\t\treturn nil\n\t}\n\n\tif existing.UID != c.UID {\n\t\treturn existing\n\t}\n\n\treturn nil","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/AdguardTeam/AdGuardHome/blob/b41aefbe51c8dde65e2c50f093996afa0502edf9/internal/client/index.go#L115-L151","documentation":"Thrown when a client's MAC address is already assigned to another client in the index. MAC addresses uniquely identify persistent clients. The error reports the existing client name and the duplicated MAC.","triggerScenarios":"Calling Storage.Add or Storage.Update with a client whose MAC equals the MAC of a different stored client, detected by clashesMAC.","commonSituations":"Two client entries (e.g. one from DHCP, one manual) carrying the same MAC, cloning client configs in the UI, imported client lists with duplicate MACs.","solutions":["Search stored clients for the MAC in the message and remove it from one of them (often a stale manually-added client)","Let the DHCP/ARP runtime source own the MAC and delete the manual duplicate","Pre-normalize the client list so MACs are unique before Add"],"exampleFix":"// before\nclient.MACs = []string{\"AA:BB:CC:DD:EE:FF\"} // already on client \"phone\"\ns.Add(ctx, client)\n\n// after\nclient.MACs = nil\ns.Add(ctx, client)","handlingStrategy":"validation","validationCode":"usedMACs := map[string]string{}\nfor _, p := range existing {\n    for _, m := range p.MACs { usedMACs[strings.ToLower(m)] = p.Name }\n}\nfor _, m := range c.MACs {\n    if owner, ok := usedMACs[strings.ToLower(m)]; ok && owner != c.Name { /* clash */ }\n}","typeGuard":null,"tryCatchPattern":"if err := s.Add(ctx, c); err != nil && strings.Contains(err.Error(), \"uses the same MAC\") { c.MACs = nil; _ = s.Add(ctx, c) }","preventionTips":["Normalize MAC casing before comparison","Avoid manually adding clients that DHCP/ARP sources already provide"],"tags":["client","mac","duplicate","validation"],"backgroundTag":"duplicate-identifier-conflict","analyzedSha":"b41aefbe51c8dde65e2c50f093996afa0502edf9","analyzedAt":"2026-08-27T04:57:55.097Z","schemaVersion":2},"datasetVersion":"2026-08-27T08:17:20.692Z"}