apache/beam · critical
zero length data for
Error message
zero length data for %v:
What it means
PersistBundle processes each output datum's bytes and expects at least the windowed-value header. An empty data slice cannot contain any elements, so prism panics — a bundle sent data with zero length for an output, violating the element protocol.
Solutions
- Upgrade SDK and prism to matching Beam versions
- Inspect logs for the transform/output named in the panic to find the producing stage
- Report a bug with the bundle/transform details if the SDK legitimately emits empty data
- Retry the job to rule out transient transport corruption
Defensive patterns
Strategy: validation
Validate before calling
for _, d := range data { if len(d) == 0 { return errors.New("empty data blob in bundle output") } } Try / catch
defer func() { if r := recover(); r != nil { log.Errorf("persist bundle panicked: %v", r) } }() Prevention
- Match SDK/harness and prism versions to avoid framing protocol skew
- Monitor transport layers for truncation/empty frame bugs
- File SDK bugs with the output/transform named in the panic message
When it happens
Trigger: In PersistBundle, a datum in the data list for an output has len(datum) == 0: the SDK/harness streamed an empty byte blob for an output that should carry encoded elements.
Common situations: Harness/SDK bug emitting empty data frames; network or transport layer truncation producing zero-length payloads; version skew in the element data framing protocol.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- couldn't decode characteristic for variant
- error decoding append bag user state window key
- error decoding residual header:
- error decoding watermarks
- error re-encoding characteristic for variant
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/28d70abd5cbcfbee.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/go/pkg/beam/runners/prism/internal/engine/elementmanager.go:888
// be scheduled when this stage's output watermark is held back. Only needed
// once something self checkpoints, so pipelines that never do keep their
// previous bundle scheduling exactly.
if len(residuals.Data) > 0 {
em.sawResidual.Store(true)
}
var changedConsumers set[string]
if em.sawResidual.Load() {
changedConsumers = set[string]{}
}
var seq int
for output, data := range d.Raw {
info := col2Coders[output]
var newPending []element
slog.Debug("PersistBundle: processing output", "bundle", rb, slog.String("output", output))
for _, datum := range data {
buf := bytes.NewBuffer(datum)
if len(datum) == 0 {
panic(fmt.Sprintf("zero length data for %v: ", output))
}
for {
var rawBytes bytes.Buffer
tee := io.TeeReader(buf, &rawBytes)
ws, et, pn, err := exec.DecodeWindowedValueHeader(info.WDec, tee)
if err != nil {
if err == io.EOF {
break
}
slog.Error("PersistBundle: error decoding watermarks", "error", err, "bundle", rb, slog.String("output", output))
panic("error decoding watermarks")
}
if len(ws) == 0 {
slog.Warn("PersistBundle: sdk provided a windowed value header 0 windows", "bundle", rb)
}
// TODO: Optimize unnecessary copies. This is doubleteeing.
elmBytes := info.EDec(tee)
var keyBytes []byteView on GitHub (pinned to 12126d8942)