kataras/iris · error

iris: switch: hosts: invalid target host: "%s"

Error message

iris: switch: hosts: invalid target host: "%s"

What it means

When building switch cases from hosts, each target must be a bare host (e.g. "example.com"), not a full absolute URL, because the switch redirects between hosts rather than URLs. If the target parses as an absolute URL (has a scheme), hostApp panics with this message. It protects users from confusing host-redirect semantics with URL redirects.

Source

Thrown at apps/switch_hosts.go:105

		return nil
	}

	switch target := host.Target.(type) {
	case context.Application:
		return target.(*iris.Application)
	case string:
		// Check if the given target is an application name, if so
		// we must not redirect (loop) we must serve the request
		// using that app.
		if targetApp, ok := context.GetApplication(target); ok {
			// It's always iris.Application so we are totally safe here.
			return targetApp.(*iris.Application)
		}
		// If it's a real host, warn the user of invalid input.
		u, err := url.Parse(target)
		if err == nil && u.IsAbs() {
			// remember, we redirect hosts, not full URLs here.
			panic(fmt.Sprintf(`iris: switch: hosts: invalid target host: "%s"`, target))
		}

		if regex := regexp.MustCompile(host.Pattern); regex.MatchString(target) {
			panic(fmt.Sprintf(`iris: switch: hosts: loop detected between expression: "%s" and target host: "%s"`, host.Pattern, host.Target))
		}

		return newHostRedirectApp(target, HostsRedirectCode)
	default:
		panic(fmt.Sprintf("iris: switch: hosts: invalid target type: %T", target))
	}
}

func hostFilter(expr string) iris.Filter {
	regex := regexp.MustCompile(expr)
	return func(ctx iris.Context) bool {
		return regex.MatchString(ctx.Host())
	}
}

View on GitHub (pinned to 7bedaf55a0)

Solutions

  1. Strip the scheme (and path) from the target so it is just the hostname
  2. Use url.Parse in your own code and pass u.Host to the provider
  3. Store hostnames only in configuration files/env vars

Example fix

// before
hosts := iris.Hosts{"example.com": "https://other.com"}
// after
u, _ := url.Parse("https://other.com")
hosts := iris.Hosts{"example.com": u.Host}
Defensive patterns

Strategy: validation

Validate before calling

for target, app := range hosts {
	if u, err := url.Parse(target); err == nil && u.IsAbs() {
		return fmt.Errorf("host target %q must be a bare host, not a URL", target)
	}
}

Type guard

func isBareHost(target string) bool {
	u, err := url.Parse(target)
	return err == nil && !u.IsAbs()
}

Try / catch

defer func() {
	if r := recover(); r != nil {
		if s, ok := r.(string); ok && strings.Contains(s, "invalid target host") {
			log.Fatalf("switch hosts misconfigured: %s", s)
		}
		panic(r)
	}
}()

Prevention

When it happens

Trigger: Registering a host entry whose target is "https://example.com" or "http://example.com/path" instead of "example.com"; values read from config that include a scheme.

Common situations: Copy-pasting full URLs from a browser; environment variables storing complete site URLs; mixing up SwitchHosts (hosts) with URL redirect handlers.

Related errors


AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30). Data as JSON: /api/errors/6642e3463c1c3202. Report an issue: GitHub.