cilium/cilium · error

%s does not match the <name>.<namespace>(.svc) form

Error message

%s does not match the <name>.<namespace>(.svc) form

What it means

ServiceURLToNamespacedName parses a service host in the form <name>.<namespace> or <name>.<namespace>.svc into a NamespacedName. It fails when the host splits into fewer than two dot-separated tokens — i.e. there is no namespace part. resolve calls it to convert FQDN-style service names into lookup keys.

Source

Thrown at pkg/dial/resolver.go:228

// as a fallback when the frontends table takes too long to be initialized.
func (sr *lbServiceResolver) resolveFromAPIServer(ctx context.Context, nsname types.NamespacedName) string {
	svc, err := sr.cs.Slim().CoreV1().Services(nsname.Namespace).Get(ctx, nsname.Name, metav1.GetOptions{})
	if err != nil {
		return ""
	}

	if _, err := netip.ParseAddr(svc.Spec.ClusterIP); err != nil {
		// The ClusterIP is not a valid IP address (e.g., headless service)
		return ""
	}

	return svc.Spec.ClusterIP
}

func ServiceURLToNamespacedName(host string) (types.NamespacedName, error) {
	tokens := strings.Split(host, ".")
	if len(tokens) < 2 {
		return types.NamespacedName{}, fmt.Errorf("%s does not match the <name>.<namespace>(.svc) form", host)
	}

	if len(tokens) >= 3 && tokens[2] != "svc" {
		return types.NamespacedName{}, fmt.Errorf("%s does not match the <name>.<namespace>(.svc) form", host)
	}

	return types.NamespacedName{Namespace: tokens[1], Name: tokens[0]}, nil
}

var _ Resolver = (*ServiceBackendResolver)(nil)

type ServiceBackendResolver struct {
	db        *statedb.DB
	frontends statedb.Table[*loadbalancer.Frontend]

	ignoredInitializers []string

	// affinityCache is leveraged to preserve backend affinity when the resolver

View on GitHub (pinned to ac7b90affa)

Solutions

  1. Use the fully qualified form: <name>.<namespace> (e.g. mysvc.default) or mysvc.default.svc
  2. Use k8s short name only when the client supports cluster-local short-name expansion instead of this resolver
  3. Validate the host string before calling resolve
  4. Check policy/config sources that generate the URL for missing namespace suffixes

Example fix

// before
resolve("http://mysvc")
// after
resolve("http://mysvc.default.svc")
Defensive patterns

Strategy: validation

Validate before calling

func isValidSvcHost(host string) bool {
	tokens := strings.Split(host, ".")
	return len(tokens) >= 2 && (len(tokens) == 2 || tokens[2] == "svc")
}

Type guard

func isNamespacedSvcHost(host string) bool {
	parts := strings.Split(host, ".")
	return len(parts) >= 2 && parts[0] != "" && parts[1] != ""
}

Try / catch

nn, err := dial.ServiceURLToNamespacedName(host)
if err != nil {
	return fmt.Errorf("cannot resolve service host %q: %w (use <name>.<namespace>.svc form)", host, err)
}

Prevention

When it happens

Trigger: Calling ServiceBackendResolver.resolve / ServiceURLToNamespacedName with a host like 'mysvc' or 'localhost' — no dot-separated namespace component.

Common situations: Dialing a bare service name without a namespace; a URL whose host was misconfigured (missing .default.svc suffix); a CiliumNetworkPolicy or upstream config referencing a short name where the resolver requires the FQDN form.

Related errors


AI-assisted analysis of cilium/cilium@ac7b90affa (2026-08-31). Data as JSON: /api/errors/013b52b80ba042ce. Report an issue: GitHub.