thanos-io/thanos · error

creating limiter

Error message

creating limiter

What it means

runReceive builds the limit enforcement component with receive.NewLimiter, which constructs a reloader tied to the limits config file, Prometheus registry, and reload timer. A failure here (e.g. the limiter cannot set up its config watcher or internal state) is wrapped with 'creating limiter' and receive refuses to start.

Solutions

  1. Check the wrapped inner error for the precise cause (limiter construction failure).
  2. Verify --receive.limits-config-reload-timer is a valid Go duration (e.g. 3s) if set.
  3. Ensure the limits config file (if provided) is valid and readable so the limiter's initial load succeeds.
  4. Upgrade to a Thanos release where any known NewLimiter initialization bug is fixed.

Example fix

// before
thanos receive --receive.limits-config-reload-timer=notaduration
// after
thanos receive --receive.limits-config-reload-timer=3s
Defensive patterns

Strategy: validation

Validate before calling

if _, err := time.ParseDuration(reloadTimer); err != nil {
  return fmt.Errorf("invalid --receive.limits-config-reload-timer: %w", err)
}

Try / catch

if err := run(); err != nil {
  if strings.Contains(err.Error(), "creating limiter") {
    log.Errorf("limiter init failed, check config/timer flags: %v", err)
  }
}

Prevention

When it happens

Trigger: Starting `thanos receive` when receive.NewLimiter(conf.writeLimitsConfig, reg, receiveMode, logger, conf.limitsConfigReloadTimer) returns an error — typically because the underlying config content provider fails its initial load or the reload timer/registry setup fails.

Common situations: Invalid --receive.limits-config-reload-timer duration value; limiter's initial config fetch failing; internal incompatibility after a Thanos upgrade.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/91a5c2e58be70c7c. Report an issue: GitHub.

Appendix: source

Thrown at cmd/thanos/receive.go:272

	)
	writer := receive.NewWriter(log.With(logger, "component", "receive-writer"), dbs, &receive.WriterOptions{
		TooFarInFutureTimeWindow: int64(time.Duration(*conf.tsdbTooFarInFutureTimeWindow)),
	})

	var limitsConfig *receive.RootLimitsConfig
	if conf.writeLimitsConfig != nil {
		limitsContentYaml, err := conf.writeLimitsConfig.Content()
		if err != nil {
			return errors.Wrap(err, "get content of limit configuration")
		}
		limitsConfig, err = receive.ParseRootLimitConfig(limitsContentYaml)
		if err != nil {
			return errors.Wrap(err, "parse limit configuration")
		}
	}
	limiter, err := receive.NewLimiter(conf.writeLimitsConfig, reg, receiveMode, log.With(logger, "component", "receive-limiter"), conf.limitsConfigReloadTimer)
	if err != nil {
		return errors.Wrap(err, "creating limiter")
	}

	webHandler := receive.NewHandler(log.With(logger, "component", "receive-handler"), &receive.Options{
		Writer:               writer,
		ListenAddress:        conf.rwAddress,
		Registry:             reg,
		Endpoint:             conf.endpoint,
		TenantHeader:         conf.tenantHeader,
		TenantField:          conf.tenantField,
		DefaultTenantID:      conf.defaultTenantID,
		ReplicaHeader:        conf.replicaHeader,
		ReplicationFactor:    conf.replicationFactor,
		RelabelConfigs:       relabelConfig,
		ReceiverMode:         receiveMode,
		Tracer:               tracer,
		TLSConfig:            rwTLSConfig,
		SplitTenantLabelName: conf.splitTenantLabelName,
		DialOpts:             dialOpts,

View on GitHub (pinned to 35b8b99117)