{"record":{"id":"c3b135e5ab339c3c","repo":"tsenart/vegeta","slug":"must-specify-at-least-resolver-address","errorCode":null,"errorMessage":"must specify at least resolver address","messagePattern":"must specify at least resolver address","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/resolver/resolver.go","lineNumber":26,"sourceCode":"\t\"strconv\"\n\t\"strings\"\n\t\"sync/atomic\"\n)\n\ntype resolver struct {\n\taddrs  []string\n\tdialer *net.Dialer\n\tidx    uint64\n}\n\n// NewResolver - create a new instance of a dns resolver for plugging\n// into net.DefaultResolver.  Addresses should be a list of\n// ip addrs and optional port numbers, separated by colon.\n// For example: 1.2.3.4:53 and 1.2.3.4 are both valid.  In the absence\n// of a port number, 53 will be used instead.\nfunc NewResolver(addrs []string) (*net.Resolver, error) {\n\tif len(addrs) == 0 {\n\t\treturn nil, errors.New(\"must specify at least resolver address\")\n\t}\n\tcleanAddrs, err := normalizeAddrs(addrs)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &net.Resolver{\n\t\tPreferGo: true,\n\t\tDial:     (&resolver{addrs: cleanAddrs, dialer: &net.Dialer{}}).dial,\n\t}, nil\n}\n\nfunc normalizeAddrs(addrs []string) ([]string, error) {\n\tnormal := make([]string, len(addrs))\n\tfor i, addr := range addrs {\n\n\t\t// if addr has no port, give it 53\n\t\tif !strings.Contains(addr, \":\") {\n\t\t\taddr += \":53\"","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/tsenart/vegeta/blob/cf5811269046c672a604b1eb352204d30f16ae4a/internal/resolver/resolver.go#L8-L44","documentation":"NewResolver in internal/resolver returns this error when given an empty address list. A custom resolver needs at least one DNS server address to replace net.DefaultResolver's behavior.","triggerScenarios":"Calling resolver.NewResolver(nil) or NewResolver([]string{}) — e.g. constructing an attacker with resolver addresses sourced from an empty flag/env value.","commonSituations":"Empty `-dns` style flag, config file with no resolver entries, or splitting an empty string into a zero-length slice.","solutions":["Pass at least one address, e.g. NewResolver([]string{\"8.8.8.8:53\"}).","Trim and check the addresses input before calling NewResolver and fall back to net.DefaultResolver if empty.","Fix the flag/config parsing so an empty value doesn't produce a nil/empty slice passed as non-optional."],"exampleFix":"// before\nr, err := resolver.NewResolver(addrs) // addrs == nil\n// after\nif len(addrs) == 0 { addrs = []string{\"8.8.8.8:53\"} }\nr, err := resolver.NewResolver(addrs)","handlingStrategy":"validation","validationCode":"if len(addrs) == 0 {\n    addrs = nil // fall back to net.DefaultResolver\n}\nvar r *net.Resolver\nif len(addrs) > 0 {\n    r, err = resolver.NewResolver(addrs)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default resolver flags to a sane value like 8.8.8.8:53","Trim/split flag strings carefully to avoid empty slices","Fall back to net.DefaultResolver when the list is empty"],"tags":["dns","resolver","validation"],"backgroundTag":"missing-required-parameter","analyzedSha":"cf5811269046c672a604b1eb352204d30f16ae4a","analyzedAt":"2026-08-31T11:04:20.464Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}