kopia/kopia · error

unable to create throttler

Error message

unable to create throttler

What it means

addThrottler wraps an error from throttling.NewThrottler, which builds the token-bucket rate limiter applied to blob storage operations. Failure means the throttling configuration (limits) is invalid, so the repository cannot be wrapped in a throttled storage layer and open aborts.

Solutions

  1. Inspect the wrapped cause; it names the invalid throttling parameter.
  2. Check the throttling limits in your local Kopia configuration (kopia repository status shows them).
  3. Remove or correct invalid values — rates must be positive (or unset/0 for no limit) and burst values sane.
  4. Re-set limits with valid values: kopia repository set-parameters --max-download-speed etc.

Example fix

// before: invalid limit
limits := throttling.Limits{DownloadSpeed: -100}
// after: validate before opening
if limits.DownloadSpeed < 0 { limits.DownloadSpeed = 0 } // 0 = unlimited
rep, err := openWithConfig(ctx, st, pass, limits)
Defensive patterns

Strategy: validation

Validate before calling

// Go: validate throttling limits before open
func validLimits(l throttling.Limits) error {
    if l.DownloadSpeed < 0 || l.UploadSpeed < 0 || l.UploadSpeedBytesPerSecond < 0 {
        return errors.New("throttle rates must be non-negative")
    }
    return nil
}

Try / catch

st, throttler, err := addThrottler(storage, limits)
if err != nil && strings.Contains(err.Error(), "unable to create throttler") {
    return fmt.Errorf("invalid throttling config: %w", err)
}

Prevention

When it happens

Trigger: openWithConfig calls addThrottler with throttling.Limits derived from repository/CLI options; NewThrottler returns an error when the limits are invalid (e.g. negative or nonsensical download/upload/uploadUnpacked rates or burst values configured).

Common situations: User sets custom throttling limits via kopia configuration (e.g. --max-download-speed, max-upload-speed) with zero/negative/invalid values; corrupted local config file with bad throttling fields.

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 kopia/kopia@82495e54b5 (2026-09-07). Data as JSON: /api/errors/45962af149393247. Report an issue: GitHub.

Appendix: source

Thrown at repo/open.go:455

	return beforeop.NewWrapper(st, nil, nil, nil, func(_ context.Context, id blob.ID, opts *blob.PutOptions) error {
		for _, prefix := range prefixes {
			if strings.HasPrefix(string(id), string(prefix)) {
				opts.RetentionMode = r.RetentionMode
				opts.RetentionPeriod = r.RetentionPeriod

				break
			}
		}

		return nil
	})
}

func addThrottler(st blob.Storage, limits throttling.Limits) (blob.Storage, throttling.SettableThrottler, error) {
	throttler, err := throttling.NewThrottler(limits, throttlingWindow, throttleBucketInitialFill)
	if err != nil {
		return nil, nil, errors.Wrap(err, "unable to create throttler")
	}

	return throttling.NewWrapper(st, throttler), throttler, nil
}

func upgradeLockMonitor(
	fmgr *format.Manager,
	upgradeOwnerID string,
	st blob.Storage,
	now func() time.Time,
	onFatalError func(err error),
	ignoreMissingRequiredFeatures bool,
) blob.Storage {
	var (
		m             sync.RWMutex
		lastCheckTime time.Time
	)

View on GitHub (pinned to 82495e54b5)