kubernetes/kops · error

host is empty

Error message

host is empty

What it means

Dial validates that the address it will connect to is non-empty after optional bastion substitution. If host is "" and useBastion is false (or the bastion substitution was skipped), there is nothing to dial, so the library returns this error rather than attempting a meaningless TCP connection. It signals that the caller supplied an empty target address.

Source

Thrown at pkg/dump/dumper.go:682

var _ sshClientFactory = &sshClientFactoryImplementation{}

// HasBastion implements sshClientFactory::HasBastion
func (f *sshClientFactoryImplementation) HasBastion() bool {
	return f.bastion != ""
}

// Dial implements sshClientFactory::Dial
func (f *sshClientFactoryImplementation) Dial(ctx context.Context, host string, useBastion bool) (sshClient, error) {
	addr := host
	if useBastion {
		if f.bastion == "" {
			return nil, fmt.Errorf("bastion is not set, but useBastion is true")
		}
		addr = f.bastion
	}

	if addr == "" {
		return nil, fmt.Errorf("host is empty")
	}
	addr = net.JoinHostPort(addr, "22")
	d := net.Dialer{
		Timeout: 5 * time.Second,
	}
	conn, err := d.DialContext(ctx, "tcp", addr)
	if err != nil {
		return nil, fmt.Errorf("error dialing tcp %s: %w", addr, err)
	}

	// We have a TCP connection; we will force-close it to support context cancellation

	var client *ssh.Client
	finished := make(chan error)
	go func() {
		c, chans, reqs, err := ssh.NewClientConn(conn, addr, f.sshConfig)
		if err == nil {
			client = ssh.NewClient(c, chans, reqs)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Filter or skip entries with empty host/IP before calling Dial
  2. Re-fetch instance addresses from the cloud provider (the instance may have no recorded IP yet) and retry
  3. Log the offending record and exclude it from the dump target list

Example fix

// before
client, err := factory.Dial(ctx, node.Status.Addresses["internalIP"], false)

// after
addr := node.Status.Addresses["internalIP"]
if addr == "" {
	klog.Warningf("skipping node %s: no address", node.Name)
	return nil
}
client, err := factory.Dial(ctx, addr, false)
Defensive patterns

Strategy: validation

Validate before calling

if host == "" {
	return fmt.Errorf("refusing to dial: empty host address")
}
client, err := factory.Dial(ctx, host, false)

Type guard

func hasAddress(host string) bool { return strings.TrimSpace(host) != "" }

Try / catch

client, err := factory.Dial(ctx, host, false)
if err != nil {
	if strings.Contains(err.Error(), "host is empty") {
		klog.Warningf("skipping target with empty address")
		return nil
	}
	return err
}

Prevention

When it happens

Trigger: Calling Dial(ctx, "", false) — i.e. an empty host string — or Dial(ctx, "", true) would have hit the bastion check first; this error fires when addr remains "" after the useBastion block, meaning host was "" and useBastion was false.

Common situations: Instance list built from kops cluster state where a node has no external/internal IP recorded (e.g. instance not yet registered, terminated node, or API returning empty address fields); passing an unset string variable for host.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/ab0b62ca1273bb32. Report an issue: GitHub.