{"record":{"id":"bd1b12357c2a71b5","repo":"thanos-io/thanos","slug":"stat-v","errorCode":null,"errorMessage":"stat %v","messagePattern":"stat %v","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/block/block.go","lineNumber":354,"sourceCode":"\t\t}\n\n\t\tmf := metadata.File{\n\t\t\tRelPath:   filepath.Join(ChunksDirname, f.Name()),\n\t\t\tSizeBytes: fi.Size(),\n\t\t}\n\t\tif hf != metadata.NoneFunc && !f.IsDir() {\n\t\t\th, err := metadata.CalculateHash(filepath.Join(blockDir, ChunksDirname, f.Name()), hf, logger)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, errors.Wrapf(err, \"calculate hash %v\", filepath.Join(ChunksDirname, f.Name()))\n\t\t\t}\n\t\t\tmf.Hash = &h\n\t\t}\n\t\tres = append(res, mf)\n\t}\n\n\tindexFile, err := os.Stat(filepath.Join(blockDir, IndexFilename))\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"stat %v\", filepath.Join(blockDir, IndexFilename))\n\t}\n\tmf := metadata.File{\n\t\tRelPath:   indexFile.Name(),\n\t\tSizeBytes: indexFile.Size(),\n\t}\n\tif hf != metadata.NoneFunc {\n\t\th, err := metadata.CalculateHash(filepath.Join(blockDir, IndexFilename), hf, logger)\n\t\tif err != nil {\n\t\t\treturn nil, errors.Wrapf(err, \"calculate hash %v\", indexFile.Name())\n\t\t}\n\t\tmf.Hash = &h\n\t}\n\tres = append(res, mf)\n\n\tmetaFile, err := os.Stat(filepath.Join(blockDir, MetaFilename))\n\tif err != nil {\n\t\treturn nil, errors.Wrapf(err, \"stat %v\", filepath.Join(blockDir, MetaFilename))\n\t}","sourceCodeStart":336,"sourceCodeEnd":372,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/block/block.go#L336-L372","documentation":"GatherFileStats stats the block's index file (<blockDir>/index) and wraps the os.Stat error with this message. The index file is a mandatory part of every TSDB block; its absence means the block is incomplete or corrupted on disk.","triggerScenarios":"upload() calls GatherFileStats on a block dir where <blockDir>/index does not exist (never written or deleted) or cannot be stat'ed due to permissions/I-O errors.","commonSituations":"Incomplete block left by a crashed Prometheus (head compaction interrupted); retention/cleanup removed the index prematurely; wrong data dir; blocks partially restored from backup missing index.","solutions":["Verify index exists: ls <blockDir>/index. If missing, the block is incomplete — delete it or re-create it from a healthy replica.","Check permissions on the block dir and index file.","Ensure the block is fully written (block ID dir contains meta.json, index, chunks/) before uploading.","Investigate why Prometheus did not finish writing the block (crash logs, OOM)."],"exampleFix":"// before\nindexFile, err := os.Stat(filepath.Join(blockDir, IndexFilename))\nif err != nil {\n\treturn nil, errors.Wrapf(err, \"stat %v\", filepath.Join(blockDir, IndexFilename))\n}\n// after\nindexPath := filepath.Join(blockDir, IndexFilename)\nindexFile, err := os.Stat(indexPath)\nif os.IsNotExist(err) {\n\treturn nil, errors.Errorf(\"block %s is incomplete: index file %s missing\", blockDir, indexPath)\n} else if err != nil {\n\treturn nil, errors.Wrapf(err, \"stat %v\", indexPath)\n}","handlingStrategy":"validation","validationCode":"indexPath := filepath.Join(blockDir, \"index\")\nif fi, err := os.Stat(indexPath); err != nil {\n\treturn fmt.Errorf(\"block %s missing index: %w\", blockDir, err)\n} else if fi.Size() == 0 {\n\treturn fmt.Errorf(\"block %s has empty index file\", blockDir)\n}","typeGuard":"func hasIndexFile(blockDir string) bool {\n\tfi, err := os.Stat(filepath.Join(blockDir, \"index\"))\n\treturn err == nil && !fi.IsDir() && fi.Size() > 0\n}","tryCatchPattern":"files, err := block.GatherFileStats(blockDir, hashFunc, logger)\nif err != nil && os.IsNotExist(errors.Unwrap(err)) {\n\treturn skipIncompleteBlock(blockDir) // quarantine/delete, don't retry\n}","preventionTips":["Only ship blocks whose directory contains meta.json, index and chunks/.","Investigate Prometheus crashes that leave half-written blocks (OOM, kill -9).","Do not remove index files manually or via custom cleanup scripts.","Use block loader / bucket verify tooling to detect incomplete blocks early."],"tags":["filesystem","tsdb","thanos"],"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"}