apache/beam · error
can't apply processing delay of less than a millisecond. Got
Error message
can't apply processing delay of less than a millisecond. Got: %v
What it means
AfterProcessingTime triggers quantize delays to whole milliseconds, so PlusDelay rejects delays smaller than one millisecond by panicking. This enforces the documented minimum resolution of processing-time trigger transforms.
Source
Thrown at sdks/go/pkg/beam/core/graph/window/trigger/trigger.go:158
// Eg. A period of 20 with an offset of 45 would have alignments at 5,25,45,65 etc.
// Timestamps would be transformed as follows: 0 to 5 would be transformed to 5,
// 6 to 25 would be transformed to 25, 26 to 45 would be transformed to 45, and so on.
type AlignToTransform struct {
Period, Offset int64 // in milliseconds
}
// String implements the Stringer interface and returns trigger details as a string.
func (t *AlignToTransform) String() string {
return fmt.Sprintf("%#v", t)
}
func (AlignToTransform) timestampTransform() {}
// PlusDelay configures an AfterProcessingTime trigger to fire after a specified delay,
// no smaller than a millisecond.
func (t *AfterProcessingTimeTrigger) PlusDelay(delay time.Duration) *AfterProcessingTimeTrigger {
if delay < time.Millisecond {
panic(fmt.Errorf("can't apply processing delay of less than a millisecond. Got: %v", delay))
}
t.timestampTransforms = append(t.timestampTransforms, DelayTransform{Delay: int64(delay / time.Millisecond)})
return t
}
// AlignedTo configures an AfterProcessingTime trigger to fire
// at the smallest multiple of period since the offset greater than the first element timestamp.
//
// * Period may not be smaller than a millisecond.
// * Offset may be a zero time (time.Time{}).
func (t *AfterProcessingTimeTrigger) AlignedTo(period time.Duration, offset time.Time) *AfterProcessingTimeTrigger {
if period < time.Millisecond {
panic(fmt.Errorf("can't apply an alignment period of less than a millisecond. Got: %v", period))
}
offsetMillis := int64(0)
if !offset.IsZero() {
// TODO: Change to call UnixMilli() once we move to only supporting a go version > 1.17.
offsetMillis = offset.Unix()*1e3 + int64(offset.Nanosecond())/1e6View on GitHub (pinned to 12126d8942)
Solutions
- Use a delay of at least time.Millisecond.
- Clamp the computed delay to time.Millisecond as a floor before calling PlusDelay.
- If sub-millisecond timing is truly required, this trigger API cannot support it; redesign around a coarser granularity.
- Verify duration arithmetic units (ns-based time.Duration values are easily mis-scaled).
Example fix
// before
t := trigger.AfterProcessingTime().PlusDelay(500 * time.Microsecond)
// after
d := 500 * time.Microsecond
if d < time.Millisecond { d = time.Millisecond }
t := trigger.AfterProcessingTime().PlusDelay(d) Defensive patterns
Strategy: validation
Validate before calling
if delay < time.Millisecond { return fmt.Errorf("delay must be >= 1ms, got %v", delay) } Try / catch
defer func() {
if r := recover(); r != nil {
if strings.Contains(fmt.Sprint(r), "processing delay") { return ErrDelayTooSmall }
panic(r)
}
}() Prevention
- Floor computed delays at time.Millisecond
- Watch time.Duration unit arithmetic (values are nanoseconds)
- Note the API's documented millisecond minimum
When it happens
Trigger: Calling PlusDelay with a duration below time.Millisecond, e.g. PlusDelay(500 * time.Microsecond) or a sub-millisecond value computed at runtime.
Common situations: Using nanosecond/microsecond constants intended for other timing APIs; arithmetic on durations (like dividing a second by 10000) producing sub-ms values; porting code from systems with finer trigger resolution.
Understand the failure class
Background: "invalid duration" / "failed to parse duration": why your timeout, interval, or TTL string is rejected and which formats each library accepts — this error's family across 32 libraries.
Related errors
- can't apply an alignment period of less than a millisecond.
- trigger.AfterCount(%v) must be a positive integer
- AfterProcessingTime trigger set without a delay or alignment
- GroupIntoBatches: %w
- GroupIntoBatchesWithShardedKey: %w
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/3b7640653a0e2308.
Report an issue: GitHub.