apache/beam · error
failed to receive header
Error message
failed to receive header
What it means
PutArtifact expects the first message on the gRPC stream to be a header carrying artifact metadata. If ps.Recv() fails (stream error, client disconnect, cancellation), the error is wrapped with this message.
Source
Thrown at sdks/go/pkg/beam/artifact/gcsproxy/staging.go:126
if a.Sha256 == "" {
a.Sha256 = info.hash
}
if info.hash != a.Sha256 {
return nil, errors.Errorf("staged artifact for %v has invalid SHA256: %v, want %v", a.Name, info.hash, a.Sha256)
}
loc = append(loc, &jobpb.ProxyManifest_Location{Name: a.Name, Uri: info.object})
}
return loc, nil
}
// PutArtifact stores the given artifact in GCS.
func (s *StagingServer) PutArtifact(ps jobpb.LegacyArtifactStagingService_PutArtifactServer) error {
// Read header
header, err := ps.Recv()
if err != nil {
return errors.Wrap(err, "failed to receive header")
}
md := header.GetMetadata().GetMetadata()
if md == nil {
return errors.Errorf("expected header as first message: %v", header)
}
object := path.Join(s.root, md.Name)
// Stream content to GCS. We don't have to worry about partial
// or abandoned writes, because object writes are atomic.
ctx := ps.Context()
cl, err := gcsx.NewClient(ctx, storage.ScopeReadWrite)
if err != nil {
return errors.Wrap(err, "failed to create GCS client")
}
r := &reader{sha256W: sha256.New(), stream: ps}
if err := gcsx.WriteObject(ctx, cl, s.bucket, object, r); err != nil {View on GitHub (pinned to 12126d8942)
Solutions
- Check the wrapped err for the underlying gRPC status (Unavailable, Canceled, EOF) and reconnect/retry from the client
- Ensure the legacy staging client sends the header message first and keeps the stream open
- Increase client timeouts for large artifact uploads
Defensive patterns
Strategy: retry
Try / catch
err := stream.PutArtifact(ctx)
if status.Code(errors.Unwrap(err)...) == codes.Unavailable {
// retry with backoff, resending header first
} Prevention
- Keep the gRPC stream alive; avoid aggressive client timeouts on large artifacts
- Ensure the client sends the header immediately upon opening the stream
- Monitor network stability between client and staging service
When it happens
Trigger: Client closes or aborts the PutArtifact stream before sending the header message; gRPC transport failure; context cancelled mid-call.
Common situations: Legacy artifact staging client crashes or times out during staging; network interruption between runner and staging service; client sends no messages at all (EOF).
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- chunk send failed
- failed to send chunks for %v; close error: %v
- chunk send failed
- Logging stream terminated unexpectedly before it was closed
- expected header as first message: %v
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/5bfeff5468dbf64c.
Report an issue: GitHub.