{"record":{"id":"dc16e6b9526cf533","repo":"weaviate/weaviate","slug":"close-writer-for-file-v","errorCode":null,"errorMessage":"close writer for file: %v","messagePattern":"close writer for file: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"modules/backup-gcs/client.go","lineNumber":330,"sourceCode":"\nfunc (g *gcsClient) PutObject(ctx context.Context, backupID, key, overrideBucket, overridePath string, byes []byte) error {\n\tbucket, err := g.findBucket(ctx, overrideBucket)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"find bucket\")\n\t}\n\n\tobjectName := g.makeObjectName(overridePath, []string{backupID, key})\n\tobj := bucket.Object(objectName)\n\twriter := obj.NewWriter(ctx)\n\twriter.ContentType = \"application/octet-stream\"\n\twriter.Metadata = map[string]string{\n\t\t\"backup-id\": backupID,\n\t}\n\tif _, err := writer.Write(byes); err != nil {\n\t\treturn errors.Wrapf(err, \"write file: %v\", objectName)\n\t}\n\tif err := writer.Close(); err != nil {\n\t\treturn errors.Wrapf(err, \"close writer for file: %v\", objectName)\n\t}\n\n\tmetric, err := monitoring.GetMetrics().BackupStoreDataTransferred.GetMetricWithLabelValues(\"backup-gcs\", \"class\")\n\tif err == nil {\n\t\tmetric.Add(float64(len(byes)))\n\t}\n\n\treturn nil\n}\n\nfunc (g *gcsClient) Initialize(ctx context.Context, backupID, overrideBucket, overridePath string) error {\n\tif _, err := g.resolveBucketName(overrideBucket); err != nil {\n\t\treturn err\n\t}\n\n\tif g.config.SkipAccessCheck {\n\t\treturn nil\n\t}","sourceCodeStart":312,"sourceCodeEnd":348,"githubUrl":"https://github.com/weaviate/weaviate/blob/75aa4b6d11f8818305aafd4440b4e32794f7ca04/modules/backup-gcs/client.go#L312-L348","documentation":"With the GCS SDK, writer.Close() finalizes the resumable upload — this is where the object actually becomes visible, so most server-side rejections surface here rather than during Write. A Close error is wrapped as 'close writer for file: <objectName>' and means the object was NOT persisted despite Write returning nil.","triggerScenarios":"writer.Close() fails: GCS returns 403 on finalize (permission checked late), quota exceeded, checksum validation failure, context deadline hit while flushing the final chunk, or 503 from GCS.","commonSituations":"Service account with create-but-no-finalize permissions; project nearing storage quota; short deadlines where the final flush of a large file exceeds the remaining time; transient GCS incidents during backup.","solutions":["Retry the backup operation — a failed Close means the object does not exist, so re-uploading is safe","Verify the service account has storage.objects.create AND storage.objects.delete/update (Storage Object Admin covers it)","Check quota/storage-class settings on the bucket and project","Increase context timeout if the final flush of large objects exceeds the deadline; check the wrapped error for the HTTP status"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"func uploadFinalized(err error) bool {\n    // nil error from Close means the object exists\n    return err == nil\n}","tryCatchPattern":"if err := module.Initialize(ctx, backupID, bucket, path); err != nil {\n    if strings.Contains(err.Error(), \"close writer\") {\n        // finalize failed: object not created; retry entire operation\n    }\n}\n// GCS SDK side: always check Close, never ignore it\nw := obj.NewWriter(ctx)\nw.Write(data)\nif err := w.Close(); err != nil { return err }","preventionTips":["Always check writer.Close() — Write succeeding does not mean upload succeeded","Grant full object create/delete/update permissions (Storage Object Admin)","Monitor project storage quota before large backups","Keep headroom in the context deadline for the final flush"],"tags":["gcs","upload","close","backup"],"backgroundTag":"gcs-upload-failed","analyzedSha":"75aa4b6d11f8818305aafd4440b4e32794f7ca04","analyzedAt":"2026-09-04T14:58:20.392Z","contentChangedAt":"2026-09-04T14:58:20.392Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}