apache/beam · error

Params.MaxBufferingDuration must be >= 0; got

Error message

Params.MaxBufferingDuration must be >= 0; got %s

What it means

Params.MaxBufferingDuration was set to a negative duration, which is meaningless as a time window. validate() rejects it at pipeline-construction time so the transform never runs with an impossible configuration. Fix the Params struct before calling GroupIntoBatches.

Solutions

  1. Print the Params value and find where MaxBufferingDuration becomes negative
  2. Correct the config/arithmetic producing the negative duration, or clamp with time.Duration(0) minimum
  3. Call params.validate() yourself before building the pipeline to fail fast
  4. Remove MaxBufferingDuration (leave it 0) if buffering-time limiting is not needed

Example fix

// before
p := batch.Params{BatchSize: 100, MaxBufferingDuration: -2 * time.Second}
// after
p := batch.Params{BatchSize: 100, MaxBufferingDuration: 2 * time.Second}
Defensive patterns

Strategy: validation

Validate before calling

if p.MaxBufferingDuration < 0 { return fmt.Errorf("bad MaxBufferingDuration: %s", p.MaxBufferingDuration) }
return p.validate()

Prevention

When it happens

Trigger: Passing Params with MaxBufferingDuration set to a negative time.Duration (e.g. -5*time.Second) to GroupIntoBatches or GroupIntoBatchesWithShardedKey, which calls params.validate().

Common situations: Computing a duration from a signed config value or arithmetic that can go negative (e.g. deadline - now after the deadline passed), or typo signs when writing literals like -time.Second.

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 apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/ca329626536a3b8c. Report an issue: GitHub.

Appendix: source

Thrown at sdks/go/pkg/beam/transforms/batch/batch.go:192

	// MaxBufferingDuration, when > 0, triggers emission of a partial
	// batch after this much processing time has elapsed since the
	// first element of the current batch was buffered.
	MaxBufferingDuration time.Duration
}

func (p Params) validate() error {
	if p.BatchSize < 0 {
		return fmt.Errorf("Params.BatchSize must be >= 0; got %d", p.BatchSize)
	}
	if p.BatchSizeBytes < 0 {
		return fmt.Errorf("Params.BatchSizeBytes must be >= 0; got %d", p.BatchSizeBytes)
	}
	if p.BatchSize == 0 && p.BatchSizeBytes == 0 {
		return fmt.Errorf("Params: at least one of BatchSize or BatchSizeBytes must be > 0")
	}
	if p.MaxBufferingDuration < 0 {
		return fmt.Errorf("Params.MaxBufferingDuration must be >= 0; got %s", p.MaxBufferingDuration)
	}
	return nil
}

const (
	sizerNone      int32 = 0
	sizerPrimitive int32 = 1
)

// codecCache keeps a per-value-type ElementEncoder/Decoder pair.
type codecCache struct {
	once sync.Once
	enc  beam.ElementEncoder
	dec  beam.ElementDecoder
}

func (c *codecCache) init(t reflect.Type) {
	c.once.Do(func() {

View on GitHub (pinned to 12126d8942)