gravitational/teleport · error
cannot route to empty target host
Error message
cannot route to empty target host
What it means
NewSSHRouteMatcherFromConfig requires a target Host in SSHRouteMatcherConfig; if cfg.Host is empty it returns errEmptyHost wrapped. An SSH route matcher must know which host traffic routes to — an empty host would produce a matcher that can never route, so construction fails fast.
Source
Thrown at api/utils/route.go:64
// it will match servers listening on any port.
Port string
// Resolver can be set to override default hostname lookup
// behavior (used in tests).
Resolver HostResolver
// CaseInsensitive enabled case insensitive routing when true.
CaseInsensitive bool
// DisableUnqualifiedLookups disables lookups for unqualified hostnames.
DisableUnqualifiedLookups bool
}
// HostResolver provides an interface matching the net.Resolver.LookupHost method. Typically
// only used as a means of overriding dns resolution behavior in tests.
type HostResolver interface {
// LookupHost performs a hostname lookup. See net.Resolver.LookupHost for details.
LookupHost(ctx context.Context, host string) (addrs []string, err error)
}
var errEmptyHost = errors.New("cannot route to empty target host")
// NewSSHRouteMatcherFromConfig sets up an ssh route matcher from the supplied configuration.
func NewSSHRouteMatcherFromConfig(cfg SSHRouteMatcherConfig) (*SSHRouteMatcher, error) {
if cfg.Host == "" {
return nil, trace.Wrap(errEmptyHost)
}
if cfg.Resolver == nil {
cfg.Resolver = net.DefaultResolver
}
m := newSSHRouteMatcher(cfg)
return &m, nil
}
// NewSSHRouteMatcher builds a new matcher for ssh routing decisions.
func NewSSHRouteMatcher(host, port string, caseInsensitive bool) SSHRouteMatcher {
return newSSHRouteMatcher(SSHRouteMatcherConfig{View on GitHub (pinned to 1283425b60)
Solutions
- Set cfg.Host to the target hostname/IP before calling NewSSHRouteMatcherFromConfig.
- Validate the upstream input (address string, server spec) so an empty/failed parse doesn't propagate an empty host into the route config.
- Reject requests earlier in the API layer with a clearer user-facing message like "target host is required".
Example fix
// before
m, err := utils.NewSSHRouteMatcherFromConfig(utils.SSHRouteMatcherConfig{Host: hostFromAddr})
// after
if hostFromAddr == "" {
return trace.BadParameter("target host is required")
}
m, err := utils.NewSSHRouteMatcherFromConfig(utils.SSHRouteMatcherConfig{Host: hostFromAddr}) Defensive patterns
Strategy: validation
Validate before calling
if routeCfg.Host == "" { return trace.BadParameter("SSH route target host is required") } Try / catch
m, err := utils.NewSSHRouteMatcherFromConfig(cfg)
if err != nil && strings.Contains(err.Error(), "empty target host") {
return trace.BadParameter("cannot route: target host missing from request")
} Prevention
- Validate the parsed target address (hostport.Parse etc.) before building route matchers.
- Never propagate empty host fields from API payloads; reject them at the handler boundary.
- Add unit tests for routing configs with missing host components.
When it happens
Trigger: Constructing an SSHRouteMatcher via NewSSHRouteMatcherFromConfig with SSHRouteMatcherConfig{Host: ""} — e.g. building a dial/route descriptor from a parsed address or server object whose hostname field is missing.
Common situations: Proxy code routing agentless SSH sessions where the target node address was not resolved; config files or API payloads omitting the host; parsing failures upstream silently leaving Host empty.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- disconnect escape sequence detected
- unable to serve request due to an app configuration error. C
- no Access Graph fetchers
- agent forwarding channel already open
- chain not allowed with an empty certificate
AI-assisted analysis of gravitational/teleport@1283425b60 (2026-09-02).
Data as JSON: /api/errors/7f20586b2fe7aac3.
Report an issue: GitHub.