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.

Solutions

  1. List local addresses with ip addr (or ifconfig) and pass one of them
  2. On multi-homed hosts pick the address of the egress interface
  3. 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

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


AI-assisted analysis of projectdiscovery/nuclei@265b3a3dec (2026-08-15). Data as JSON: /api/errors/e909864ec55784ce. Report an issue: GitHub.

Appendix: 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 properly

View on GitHub (pinned to 265b3a3dec)