{"record":{"id":"4e68f979d4acd8f5","repo":"thanos-io/thanos","slug":"existing-tsdb-block-is-invalid","errorCode":null,"errorMessage":"existing tsdb block is invalid","messagePattern":"existing tsdb block is invalid","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/verifier/safe_delete.go","lineNumber":136,"sourceCode":"\t}\n\n\tlevel.Info(ctx.Logger).Log(\"msg\", \"Marking block as deleted\", \"id\", id.String())\n\tif err := block.MarkForDeletion(ctx, ctx.Logger, ctx.Bkt, id, \"manual verify-repair\", ctx.metrics.blocksMarkedForDeletion); err != nil {\n\t\treturn errors.Wrap(err, \"marking delete from source\")\n\t}\n\treturn nil\n}\n\n// backupDownloaded is a helper function that uploads a TSDB block\n// found on disk to the given bucket. An error is returned if any operation\n// fails.\nfunc backupDownloaded(ctx context.Context, logger log.Logger, bdir string, backupBkt objstore.Bucket, id ulid.ULID) error {\n\t// Safety checks.\n\tif _, err := os.Stat(filepath.Join(bdir, \"meta.json\")); err != nil {\n\t\t// If there is any error stat'ing meta.json inside the TSDB block\n\t\t// then declare the existing block as bad and refuse to upload it.\n\t\t// TODO: Make this check more robust.\n\t\treturn errors.Wrap(err, \"existing tsdb block is invalid\")\n\t}\n\n\t// Upload the on disk TSDB block.\n\tlevel.Info(logger).Log(\"msg\", \"Uploading block to backup bucket\", \"id\", id.String())\n\tif err := block.Upload(ctx, logger, backupBkt, bdir, metadata.NoneFunc); err != nil {\n\t\treturn errors.Wrap(err, \"upload to backup\")\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":118,"sourceCodeEnd":147,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/verifier/safe_delete.go#L118-L147","documentation":"backupDownloaded validates the on-disk TSDB block by stat-ing its meta.json before uploading it to the backup bucket. If os.Stat fails for any reason, the block is declared invalid and the upload is refused, wrapping the stat error with this message.","triggerScenarios":"BackupAndDelete/BackupAndDeleteDownloaded call backupDownloaded with a block directory (bdir) where meta.json is missing, unreadable, or the path is wrong/inaccessible.","commonSituations":"Incomplete or corrupted block download on local disk; wrong --data-dir path; permissions issues on the local filesystem; partially cleaned-up block directory.","solutions":["Ensure the block directory contains a readable meta.json (ls the dir, check permissions)","Re-download/refresh the block to local disk before repairing","Verify the bdir path passed to the repair command is correct","Inspect the wrapped os.Stat error for the exact cause"],"exampleFix":"// before\n// proceeding to upload without checking meta.json\n// after\nif _, err := os.Stat(filepath.Join(bdir, \"meta.json\")); err != nil {\n\treturn errors.Wrap(err, \"existing tsdb block is invalid\")\n}","handlingStrategy":"validation","validationCode":"if _, err := os.Stat(filepath.Join(bdir, \"meta.json\")); err != nil {\n\t// re-download block or fix bdir before calling backupDownloaded\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Verify block dir contains meta.json before repair","Ensure correct --data-dir and disk permissions","Re-download corrupted/incomplete blocks"],"tags":["filesystem","tsdb-block","meta-json"],"backgroundTag":"file-not-found","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}