{"record":{"id":"5bfeff5468dbf64c","repo":"apache/beam","slug":"failed-to-receive-header","errorCode":null,"errorMessage":"failed to receive header","messagePattern":"failed to receive header","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/artifact/gcsproxy/staging.go","lineNumber":126,"sourceCode":"\t\tif a.Sha256 == \"\" {\n\t\t\ta.Sha256 = info.hash\n\t\t}\n\t\tif info.hash != a.Sha256 {\n\t\t\treturn nil, errors.Errorf(\"staged artifact for %v has invalid SHA256: %v, want %v\", a.Name, info.hash, a.Sha256)\n\t\t}\n\n\t\tloc = append(loc, &jobpb.ProxyManifest_Location{Name: a.Name, Uri: info.object})\n\t}\n\treturn loc, nil\n}\n\n// PutArtifact stores the given artifact in GCS.\nfunc (s *StagingServer) PutArtifact(ps jobpb.LegacyArtifactStagingService_PutArtifactServer) error {\n\t// Read header\n\n\theader, err := ps.Recv()\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to receive header\")\n\t}\n\tmd := header.GetMetadata().GetMetadata()\n\tif md == nil {\n\t\treturn errors.Errorf(\"expected header as first message: %v\", header)\n\t}\n\tobject := path.Join(s.root, md.Name)\n\n\t// Stream content to GCS. We don't have to worry about partial\n\t// or abandoned writes, because object writes are atomic.\n\n\tctx := ps.Context()\n\tcl, err := gcsx.NewClient(ctx, storage.ScopeReadWrite)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"failed to create GCS client\")\n\t}\n\n\tr := &reader{sha256W: sha256.New(), stream: ps}\n\tif err := gcsx.WriteObject(ctx, cl, s.bucket, object, r); err != nil {","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/artifact/gcsproxy/staging.go#L108-L144","documentation":"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.","triggerScenarios":"Client closes or aborts the PutArtifact stream before sending the header message; gRPC transport failure; context cancelled mid-call.","commonSituations":"Legacy artifact staging client crashes or times out during staging; network interruption between runner and staging service; client sends no messages at all (EOF).","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"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := stream.PutArtifact(ctx)\nif status.Code(errors.Unwrap(err)...) == codes.Unavailable {\n    // retry with backoff, resending header first\n}","preventionTips":["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"],"tags":["grpc","streaming","gcs","artifact-staging","network"],"backgroundTag":"http-request-failed","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}