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
- Strip the scheme (and path) from the target so it is just the hostname
- Use url.Parse in your own code and pass u.Host to the provider
- 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
- Strip scheme/path from targets before registration (u.Host)
- Store hostnames, not URLs, in config
- Validate all host targets at config-load time
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
- iris: switch: empty cases
- iris: switch: hosts: loop detected between expression: "%s"
- compress: response will not be compressed
- empty form
- empty form field
AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30).
Data as JSON: /api/errors/6642e3463c1c3202.
Report an issue: GitHub.