slackhq/nebula · error

stats.path should not be empty

Error message

stats.path should not be empty

What it means

For the prometheus stats sink, nebula requires stats.path — the URL path the metrics endpoint is served on — to be non-empty. loadStatsConfig returns this error when stats.listen is set but stats.path resolves to an empty string, aborting config load or reload.

Source

Thrown at stats.go:361

		cfg.graphite.protocol = c.GetString("stats.protocol", "tcp")
		cfg.graphite.host = c.GetString("stats.host", "")
		if cfg.graphite.host == "" {
			return cfg, errors.New("stats.host can not be empty")
		}
		addr, err := net.ResolveTCPAddr(cfg.graphite.protocol, cfg.graphite.host)
		if err != nil {
			return cfg, fmt.Errorf("error while setting up graphite sink: %s", err)
		}
		cfg.graphite.resolvedAddr = addr.String()
		cfg.graphite.prefix = c.GetString("stats.prefix", "nebula")
	case "prometheus":
		cfg.prom.listen = c.GetString("stats.listen", "")
		if cfg.prom.listen == "" {
			return cfg, errors.New("stats.listen should not be empty")
		}
		cfg.prom.path = c.GetString("stats.path", "")
		if cfg.prom.path == "" {
			return cfg, errors.New("stats.path should not be empty")
		}
		cfg.prom.namespace = c.GetString("stats.namespace", "")
		cfg.prom.subsystem = c.GetString("stats.subsystem", "")
	default:
		return cfg, fmt.Errorf("stats.type was not understood: %s", cfg.typ)
	}

	return cfg, nil
}

View on GitHub (pinned to dd8f660c0a)

Solutions

  1. Add `stats.path: /metrics` (or your preferred path, starting with /) under the stats block
  2. Confirm the key is inside the stats block at correct YAML indentation
  3. If you only need graphite, switch stats.type to graphite and configure stats.host instead

Example fix

# before
stats:
  type: prometheus
  listen: 127.0.0.1:8080
# after
stats:
  type: prometheus
  listen: 127.0.0.1:8080
  path: /metrics
Defensive patterns

Strategy: validation

Validate before calling

if cfg.Stats["type"] == "prometheus" && (cfg.Stats["path"] == nil || cfg.Stats["path"] == "") {
    return errors.New("stats.path must be set when stats.type is prometheus")
}

Try / catch

cfg, err := loadStatsConfig(raw)
if err != nil {
    if strings.Contains(err.Error(), "stats.path should not be empty") {
        return fmt.Errorf("prometheus stats needs stats.path, e.g. /metrics: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Configuring `stats.type: prometheus` with stats.listen but omitting or leaving stats.path empty during startup or SIGHUP reload.

Common situations: Minimal prometheus config examples that only show stats.listen; a stats.path key typo or wrong indentation; hand-written configs where the path was commented out.

Related errors


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