{"record":{"id":"e5ddec675abd6680","repo":"apache/beam","slug":"unexpected-sha256-for-sent-chunks-for-v-v-want-v","errorCode":null,"errorMessage":"unexpected SHA256 for sent chunks for %v: %v, want %v","messagePattern":"unexpected SHA256 for sent chunks for (.+?): (.+?), want (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"sdks/go/pkg/beam/artifact/stage.go","lineNumber":169,"sourceCode":"\theader := &jobpb.PutArtifactRequest{\n\t\tContent: &jobpb.PutArtifactRequest_Metadata{\n\t\t\tMetadata: pmd,\n\t\t},\n\t}\n\tif err := stream.Send(header); err != nil {\n\t\tstream.CloseAndRecv() // ignore error\n\t\treturn nil, errors.Wrapf(err, \"failed to send header for %v\", filename)\n\t}\n\tstagedHash, err := stageChunks(stream, fd)\n\tif err != nil {\n\t\t_, errClose := stream.CloseAndRecv()\n\t\treturn nil, errors.Wrapf(err, \"failed to send chunks for %v; close error: %v\", filename, errClose)\n\t}\n\tif resp, err := stream.CloseAndRecv(); err != nil && err != io.EOF {\n\t\treturn nil, errors.Wrapf(err, \"failed to close stream for %v; response: %v\", filename, resp)\n\t}\n\tif hash != stagedHash {\n\t\treturn nil, errors.Errorf(\"unexpected SHA256 for sent chunks for %v: %v, want %v\", filename, stagedHash, hash)\n\t}\n\treturn md, nil\n}\n\nfunc stageChunks(stream jobpb.LegacyArtifactStagingService_PutArtifactClient, r io.Reader) (string, error) {\n\tsha256W := sha256.New()\n\tdata := make([]byte, 1<<20)\n\tfor {\n\t\tn, err := r.Read(data)\n\t\tif n > 0 {\n\t\t\tif _, err := sha256W.Write(data[:n]); err != nil {\n\t\t\t\tpanic(err) // cannot fail\n\t\t\t}\n\n\t\t\tchunk := &jobpb.PutArtifactRequest{\n\t\t\t\tContent: &jobpb.PutArtifactRequest_Data{\n\t\t\t\t\tData: &jobpb.ArtifactChunk{\n\t\t\t\t\t\tData: data[:n],","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/apache/beam/blob/12126d8942aaf848030c478b4c6a28c6af861c66/sdks/go/pkg/beam/artifact/stage.go#L151-L187","documentation":"After streaming the file, Stage() compares the SHA256 it computed locally before upload (hash) with the hash computed while sending chunks (stagedHash). If they differ, the bytes read during upload were not identical to the file's original content, so Stage refuses to report success with 'unexpected SHA256 for sent chunks'. This is a data-integrity guard protecting against corrupted uploads or concurrent file mutation.","triggerScenarios":"The file at filename was modified or truncated by another process between computeSHA256() and os.Open()/stageChunks; the io.Reader returned short/incorrect data; a hashing bug caused sha256W to receive different bytes than were actually hashed in computeSHA256.","commonSituations":"Build systems re-writing jars/binaries while Beam stages them (e.g. Gradle/Maven still writing the artifact); shared or network filesystems serving changed content; staging the same changing temp file twice concurrently.","solutions":["Ensure the artifact file is final and immutable before calling StageDir/MultiStage — do not stage files still being written by a build tool.","Re-run staging; if the error reproduces on a stable file, verify the file content matches its expected checksum with an independent sha256sum.","Copy the artifact to a private temp location and stage that copy to eliminate concurrent-writer races.","Check computeSHA256 and the file-open order in your Beam version — if a known bug, upgrade the Beam SDK."],"exampleFix":"// before (racy)\nMultiStage(ctx, client, 10, []artifact.KeyedFile{{Key: \"jar\", Filename: \"target/app.jar\"}}, st)\n// after (snapshot to immutable temp file first)\ntmp, _ := os.CreateTemp(\"\", \"staged-*.jar\")\nsrc, _ := os.Open(\"target/app.jar\")\nio.Copy(tmp, src)\nsrc.Close(); tmp.Close()\nMultiStage(ctx, client, 10, []artifact.KeyedFile{{Key: \"jar\", Filename: tmp.Name()}}, st)","handlingStrategy":"validation","validationCode":"// before staging, confirm the file is stable and matches its expected checksum\ninfo1, _ := os.Stat(filename)\ntime.Sleep(100 * time.Millisecond)\ninfo2, _ := os.Stat(filename)\nif !info1.ModTime().Equal(info2.ModTime()) {\n\treturn fmt.Errorf(\"file %s is being modified; defer staging\", filename)\n}","typeGuard":null,"tryCatchPattern":"if _, err := artifact.Stage(ctx, client, key, filename, token); err != nil {\n\tif strings.Contains(err.Error(), \"unexpected SHA256\") {\n\t\treturn fmt.Errorf(\"artifact %s mutated during upload; rebuild and re-stage\", filename)\n\t}\n\treturn err\n}","preventionTips":["Only stage finalized, immutable build outputs.","Snapshot files to a private temp location before staging when other processes may write them.","Never stage the same changing temp file from concurrent goroutines.","Independently verify artifact checksums (sha256sum) when integrity errors reproduce."],"tags":["checksum","sha256","integrity","artifact-staging","go","beam"],"backgroundTag":"checksum-mismatch","analyzedSha":"12126d8942aaf848030c478b4c6a28c6af861c66","analyzedAt":"2026-09-13T01:50:10.254Z","contentChangedAt":"2026-09-13T01:50:10.254Z","schemaVersion":2},"datasetVersion":"2026-09-20T03:17:13.778Z"}