thanos-io/thanos · error

invalid maximum pool size

Error message

invalid maximum pool size

What it means

NewBucketedPool requires the maximum bucket size to be at least 1. A maxSize < 1 cannot host any allocation and breaks the bucket size ladder built from minSize up to maxSize. Returned at construction time.

Solutions

  1. Pass maxSize >= 1 and ensure maxSize >= minSize
  2. Validate config-derived sizes before constructing the pool
  3. Use the default pool helpers (NewDefaultChunkBytesPool) if custom sizing is not needed

Example fix

// before
pool, err := pool.NewBucketedPool[byte](1<<10, maxChunkSize, 2, 0)
// after
if maxChunkSize < (1 << 10) { maxChunkSize = 1 << 22 }
pool, err := pool.NewBucketedPool[byte](1<<10, maxChunkSize, 2, 0)
Defensive patterns

Strategy: validation

Validate before calling

if maxSize < 1 || maxSize < minSize {
    return errors.New("pool maxSize must be >= 1 and >= minSize")
}
pool, err := pool.NewBucketedPool[byte](minSize, maxSize, factor, maxTotal)

Try / catch

p, err := pool.NewBucketedPool[byte](minSize, maxSize, factor, maxTotal)
if err != nil {
    return fmt.Errorf("configuring chunk pool: %w", err)
}

Prevention

When it happens

Trigger: Calling NewBucketedPool[T](minSize, 0, ...) or negative maxSize; also occurs when minSize > maxSize such that computed sizes end up empty, but the direct trigger is maxSize < 1.

Common situations: Config flag for max chunk pool size set to 0 or unset and defaulted to 0; unit tests probing pool validation.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at pkg/pool/pool.go:62

// Useful for package internal pools.
func MustNewBucketedPool[T any](minSize, maxSize int, factor float64, maxTotal uint64) *BucketedPool[T] {
	pool, err := NewBucketedPool[T](minSize, maxSize, factor, maxTotal)
	if err != nil {
		panic(err)
	}
	return pool
}

// NewBucketedPool returns a new BucketedPool with size buckets for minSize to
// maxSize increasing by the given factor and maximum number of used items. No
// more than maxTotal items can be used at any given time unless maxTotal is set
// to 0.
func NewBucketedPool[T any](minSize, maxSize int, factor float64, maxTotal uint64) (*BucketedPool[T], error) {
	if minSize < 1 {
		return nil, errors.New("invalid minimum pool size")
	}
	if maxSize < 1 {
		return nil, errors.New("invalid maximum pool size")
	}
	if factor < 1 {
		return nil, errors.New("invalid factor")
	}

	var sizes []int

	for s := minSize; s <= maxSize; s = int(float64(s) * factor) {
		sizes = append(sizes, s)
	}
	p := &BucketedPool[T]{
		buckets:  make([]sync.Pool, len(sizes)),
		sizes:    sizes,
		maxTotal: maxTotal,
		new: func(sz int) *[]T {
			s := make([]T, 0, sz)
			return &s
		},

View on GitHub (pinned to 35b8b99117)