apache/beam · error

xlangx.RegisterExpansionForUrn

Error message

xlangx.RegisterExpansionForUrn(%q,%q) error: %v

What it means

registry.RegisterOverrideForUrn maps a transform URN to a fixed expansion address. The address must pass validateAddr (it must look like a registered handler namespace or a host:port service address); otherwise it is wrapped as "xlangx.RegisterExpansionForUrn(%q,%q) error". This guards against URN overrides pointing at addresses the resolver can never use.

Solutions

  1. Pass a valid host:port, e.g. "localhost:8097", matching the running expansion service.
  2. Ensure any namespace used as the address is registered via RegisterHandler first.
  3. Print/inspect the wrapped err to see which validateAddr rule failed.
  4. Validate the address format in config loading before calling RegisterOverrideForUrn.

Example fix

// before
err := xlangx.RegisterOverrideForUrn(urn, "localhost")
// after
err := xlangx.RegisterOverrideForUrn(urn, "localhost:8097")
Defensive patterns

Strategy: validation

Validate before calling

if _, _, err := net.SplitHostPort(expansionAddr); err != nil {
    return fmt.Errorf("expansion address %q must be host:port", expansionAddr)
}

Try / catch

if err := xlangx.RegisterOverrideForUrn(urn, addr); err != nil {
    return fmt.Errorf("configuring expansion override for %s -> %s: %w", urn, addr, err)
}

Prevention

When it happens

Trigger: Calling xlangx.RegisterOverrideForUrn(urn, addr) where addr is neither a valid handler namespace nor a valid host:port expansion service address (e.g. empty, malformed URL, missing port, unknown scheme).

Common situations: Config-file expansion addresses missing the port; passing "localhost" without a port; typos in the address; using a namespace that was never registered with RegisterHandler.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/6cf2deccb580ad60. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/core/runtime/xlangx/registry.go:199

func validateNamespace(namespace string) error {
	if strings.Contains(namespace, Separator) {
		return fmt.Errorf("invalid namespace, provide a different one: %q contains the separator %q", namespace, Separator)
	}
	if _, ok := restricted[namespace]; ok {
		return fmt.Errorf("invalide namespace, provide a different one: %q is a restricted namespace", namespace)
	}
	return nil
}

// RegisterOverrideForUrn instructs using expansionAddr for CrossLanguage
// transforms with urn. expansionAddr should either be registered with an
// Expansion handler, or an Expansion service address.
func (r *registry) RegisterOverrideForUrn(urn, expansionAddr string) error {
	r.mu.Lock()
	defer r.mu.Unlock()
	if err := r.validateAddr(expansionAddr); err != nil {
		return fmt.Errorf("xlangx.RegisterExpansionForUrn(%q,%q) error: %v", urn, expansionAddr, err)
	}
	r.urnOverrides[urn] = expansionAddr
	return nil
}

func (r *registry) validateAddr(expansionAddr string) error {
	u, err := url.Parse(expansionAddr)
	if err == nil && u.Scheme != "" && u.Host != "" {
		// This is likely a URL, so allow it.
		return nil
	}
	// Otherwise, let's check that we have a handler registered.
	ns, _ := parseAddr(expansionAddr)
	if _, ok := r.handlers[ns]; !ok {
		return fmt.Errorf("expansionAddr %q trying to use unregistered namespace: %q", expansionAddr, ns)
	}
	return nil
}

View on GitHub (pinned to 12126d8942)