projectdiscovery/nuclei · error
both follow host redirects and follow redirects specified
Error message
both follow host redirects and follow redirects specified
What it means
Variant of the source-IP check when only -source-ip is provided: nuclei verifies the address against every interface ('any'); if none owns it, startup aborts. Typical when the address is stale, belongs to another machine, or is a public/NAT address rather than one assigned locally.
Source
Thrown at internal/runner/options.go:164
if _, ok := err.(*validator.InvalidValidationError); ok {
return err
}
errs := []string{}
for _, err := range err.(validator.ValidationErrors) {
errs = append(errs, err.Namespace()+": "+err.Tag())
}
return errors.Wrap(errors.New(strings.Join(errs, ", ")), "validation failed for these fields")
}
if options.Verbose && options.Silent {
return errors.New("both verbose and silent mode specified")
}
if (options.HeadlessOptionalArguments != nil || options.ShowBrowser || options.UseInstalledChrome) && !options.Headless {
return errors.New("headless mode (-headless) is required if -ho, -sb, -sc or -lha are set")
}
if options.FollowHostRedirects && options.FollowRedirects {
return errors.New("both follow host redirects and follow redirects specified")
}
if options.ShouldFollowHTTPRedirects() && options.DisableRedirects {
return errors.New("both follow redirects and disable redirects specified")
}
// loading the proxy server list from file or cli and test the connectivity
if err := loadProxyServers(options); err != nil {
return err
}
if options.Validate {
validateTemplatePaths(options.Logger, config.DefaultConfig.TemplatesDirectory, options.Templates, options.Workflows)
}
if options.DAST {
if err := validateDASTOptions(options); err != nil {
return err
}
}
// Verify if any of the client certificate options were set since it requires all three to work properlyView on GitHub (pinned to 265b3a3dec)
Solutions
- List local addresses with ip addr (or ifconfig) and pass one of them
- On multi-homed hosts pick the address of the egress interface
- Remove -source-ip to let the OS choose the source address
Example fix
# before nuclei -source-ip 203.0.113.7 -t tpl.yaml # after nuclei -source-ip 192.168.1.20 -t tpl.yaml
Defensive patterns
Strategy: validation
Validate before calling
import "net"
func ipAnywhere(ip string) bool {
addrs, err := net.InterfaceAddrs()
if err != nil {
return false
}
for _, a := range addrs {
if ipnet, ok := a.(*net.IPNet); ok && ipnet.IP.String() == ip {
return true
}
}
return false
} Prevention
- Refresh source IPs after network changes
- Never use public or NAT addresses as -source-ip
- Let the OS choose by omitting -source-ip
When it happens
Trigger: nuclei -source-ip 203.0.113.7 on a host whose interfaces only hold 192.168.x.x; an address from a previous DHCP lease; a typo in the flag.
Common situations: Laptops roaming between networks; scripts hard-coding an old IP; users passing the target's public IP instead of a local source address.
Related errors
- headless mode (-headless) is required if -ho, -sb, -sc or -l
- both follow redirects and disable redirects specified
- prompt not found (read cap reached)
- include directive preprocessing is disabled
- could not read profile file: %w
AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15).
Data as JSON: /api/errors/e909864ec55784ce.
Report an issue: GitHub.