slackhq/nebula · error

config ' .

Error message

config '%s.%s': %w

What it means

This is a wrapping error: when newCalculatedRemotesListFromConfig fails for a specific CIDR's entry list, NewCalculatedRemotesFromConfig re-wraps the inner error as `config '<key>.<cidr>': <inner>` so the message pinpoints the exact config section. The root cause is always in the wrapped inner error (invalid type, missing mask, bad port, family mismatch).

Solutions

  1. Read the wrapped inner error after `config 'lighthouse.calculated_remotes.<cidr>':` to find the actual failure
  2. Fix the entry under the named CIDR (mask, port, or list structure) per the inner error
  3. Validate the whole calculated_remotes block offline before reload
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-validate the whole calculated_remotes section before reload:
// for each cidr key: netip.ParsePrefix(key); for each entry: map with string mask + port in 0-65535

Try / catch

_, err := NewCalculatedRemotesFromConfig(c, "lighthouse.calculated_remotes")
if err != nil {
	// err is `config '<k>.<cidr>': <inner>`; log err fully and surface the inner cause
	handleConfigError(fmt.Errorf("calculated_remotes rejected: %w", err))
}

Prevention

When it happens

Trigger: NewCalculatedRemotesFromConfig calls newCalculatedRemotesListFromConfig(cidr, rawValue) and the entry list or any single entry fails validation; the inner error is wrapped with the config key and CIDR.

Common situations: Debugging a nebula config: this outer wrapper appears in logs whenever a calculated_remotes entry is malformed — read the text after the colon for the real problem.

Related errors


AI-assisted analysis of slackhq/nebula@dd8f660c0a (2026-09-03). Data as JSON: /api/errors/be64dc5825efa957. Report an issue: GitHub.

Appendix: source

Thrown at calculated_remote.go:99

	if value == nil {
		return nil, nil
	}

	calculatedRemotes := new(bart.Table[[]*calculatedRemote])

	rawMap, ok := value.(map[string]any)
	if !ok {
		return nil, fmt.Errorf("config `%s` has invalid type: %T", k, value)
	}
	for rawCIDR, rawValue := range rawMap {
		cidr, err := netip.ParsePrefix(rawCIDR)
		if err != nil {
			return nil, fmt.Errorf("config `%s` has invalid CIDR: %s", k, rawCIDR)
		}

		entry, err := newCalculatedRemotesListFromConfig(cidr, rawValue)
		if err != nil {
			return nil, fmt.Errorf("config '%s.%s': %w", k, rawCIDR, err)
		}

		calculatedRemotes.Insert(cidr, entry)
	}

	return calculatedRemotes, nil
}

func newCalculatedRemotesListFromConfig(cidr netip.Prefix, raw any) ([]*calculatedRemote, error) {
	rawList, ok := raw.([]any)
	if !ok {
		return nil, fmt.Errorf("calculated_remotes entry has invalid type: %T", raw)
	}

	var l []*calculatedRemote
	for _, e := range rawList {
		c, err := newCalculatedRemotesEntryFromConfig(cidr, e)
		if err != nil {

View on GitHub (pinned to dd8f660c0a)