{"record":{"id":"b2e938a752ab09a9","repo":"cilium/cilium","slug":"invalid-ip-address-v-b2e938","errorCode":null,"errorMessage":"invalid IP address: %v","messagePattern":"invalid IP address: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"standalone-dns-proxy/pkg/client/client.go","lineNumber":527,"sourceCode":"\n\treturn nil\n}\n\n// updateIPToEndpoint updates the IP to endpoint table with the received identity to endpoint mappings.\nfunc (c *GRPCClient) updateIPToEndpoint(mappings []*pb.IdentityToEndpointMapping) error {\n\twtxn := c.db.WriteTxn(c.ipToEndpointTable)\n\tdefer wtxn.Abort()\n\n\t// Clear existing entries as we are replacing the entire mapping with the given snapshot.\n\tc.ipToEndpointTable.DeleteAll(wtxn)\n\n\tfor _, mapping := range mappings {\n\t\tfor _, epInfo := range mapping.GetEndpointInfo() {\n\t\t\tips := make([]netip.Addr, 0, len(epInfo.GetIp()))\n\t\t\tfor _, ip := range epInfo.GetIp() {\n\t\t\t\taddr, ok := netip.AddrFromSlice(ip)\n\t\t\t\tif !ok {\n\t\t\t\t\treturn fmt.Errorf(\"invalid IP address: %v\", ip)\n\t\t\t\t}\n\t\t\t\tips = append(ips, addr)\n\t\t\t}\n\t\t\t_, _, err := c.ipToEndpointTable.Insert(wtxn, IPtoEndpointInfo{\n\t\t\t\tIP:       ips,\n\t\t\t\tID:       epInfo.GetId(),\n\t\t\t\tIdentity: identity.NumericIdentity(mapping.GetIdentity()),\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\twtxn.Commit()\n\n\treturn nil\n}\n","sourceCodeStart":509,"sourceCodeEnd":545,"githubUrl":"https://github.com/cilium/cilium/blob/ac7b90affa4baf0642e6685319d56907b3a73a6d/standalone-dns-proxy/pkg/client/client.go#L509-L545","documentation":"updateIPToEndpointState (standalone-dns-proxy/pkg/client/client.go) converts endpoint IPs received as raw byte slices from the gRPC/proto EndpointInfo into netip.Addr via netip.AddrFromSlice. When the bytes are not a valid 4- or 16-byte IP (empty, wrong length, or corrupted), the insert into the IP-to-endpoint table is aborted with this error.","triggerScenarios":"A peer/registry sends epInfo.GetIp() bytes that fail netip.AddrFromSlice — e.g. an empty slice for an endpoint with no IPs, a 0-length or odd-length byte string, or a wire-encoding bug producing non-IP bytes.","commonSituations":"Endpoint synchronization events carrying endpoints without addresses; version skew between the sender and the standalone DNS proxy producing malformed proto payloads; corrupted registry entries.","solutions":["Log and skip the malformed mapping instead of aborting the whole update loop for other endpoints","Validate ip length (4 or 16 bytes) at the proto producer side before emitting EndpointInfo","Check the peer component version for proto schema skew and upgrade accordingly","Inspect the registry data source for entries with empty/invalid IP lists"],"exampleFix":"// before\naddr, ok := netip.AddrFromSlice(ip)\nif !ok {\n\treturn fmt.Errorf(\"invalid IP address: %v\", ip)\n}\n// after\naddr, ok := netip.AddrFromSlice(ip)\nif !ok {\n\tlog.Warnf(\"skipping endpoint %d with invalid IP %v\", epInfo.GetId(), ip)\n\tcontinue\n}","handlingStrategy":"validation","validationCode":"// validate IP bytes before trusting the mapping\nfunc validIPBytes(b []byte) bool { return len(b) == 4 || len(b) == 16 }","typeGuard":null,"tryCatchPattern":"err := c.updateIPToEndpoint(ctx, mappings)\nif err != nil && strings.Contains(err.Error(), \"invalid IP address\") {\n\t// skip bad payload and resync rather than crash the update loop\n\tlog.Warnf(\"malformed endpoint IP payload, resyncing: %v\", err)\n\treturn c.resync(ctx)\n}","preventionTips":["Validate EndpointInfo payloads at the producer side before emitting","Keep the registry peer and standalone DNS proxy versions aligned","Drop/skip endpoints that report an empty IP list instead of propagating them"],"tags":["dns","ip-address","grpc"],"backgroundTag":"invalid-ip-address","analyzedSha":"ac7b90affa4baf0642e6685319d56907b3a73a6d","analyzedAt":"2026-08-31T18:27:15.868Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}