{"record":{"id":"c31572d51b61e1a8","repo":"thanos-io/thanos","slug":"empty-external-labels-are-not-allowed-for-thanos-b","errorCode":null,"errorMessage":"empty external labels are not allowed for Thanos block.","messagePattern":"empty external labels are not allowed for Thanos block\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/block/block.go","lineNumber":134,"sourceCode":"\tif !df.IsDir() {\n\t\treturn errors.Errorf(\"%s is not a directory\", bdir)\n\t}\n\n\t// Verify dir.\n\tid, err := ulid.Parse(df.Name())\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"not a block dir\")\n\t}\n\n\tmeta, err := metadata.ReadFromDir(bdir)\n\tif err != nil {\n\t\t// No meta or broken meta file.\n\t\treturn errors.Wrap(err, \"read meta\")\n\t}\n\n\tif checkExternalLabels {\n\t\tif len(meta.Thanos.Labels) == 0 {\n\t\t\treturn errors.New(\"empty external labels are not allowed for Thanos block.\")\n\t\t}\n\t}\n\n\tmetaEncoded := strings.Builder{}\n\tmeta.Thanos.Files, err = GatherFileStats(bdir, hf, logger)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"gather meta file stats\")\n\t}\n\n\tif err := objstore.UploadDir(ctx, logger, bkt, filepath.Join(bdir, ChunksDirname), path.Join(id.String(), ChunksDirname), options...); err != nil {\n\t\treturn errors.Wrap(err, \"upload chunks\")\n\t}\n\n\tif err := objstore.UploadFile(ctx, logger, bkt, filepath.Join(bdir, IndexFilename), path.Join(id.String(), IndexFilename)); err != nil {\n\t\treturn errors.Wrap(err, \"upload index\")\n\t}\n\n\tmeta.Thanos.UploadTime = time.Now().UTC()","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/block/block.go#L116-L152","documentation":"When checkExternalLabels is true, upload() refuses to upload a block whose meta.json lacks Thanos external labels. Thanos requires external labels to build unique block IDs across replicas and to route queries; a block without them would be ambiguous in the bucket.","triggerScenarios":"Uploading a Prometheus block whose meta.json has an empty meta.Thanos.Labels map while checkExternalLabels=true (the default via block.Upload).","commonSituations":"Prometheus not configured with external_labels; meta.json written by older/tooling versions that skipped Thanos labels; hand-crafted meta.json files; sidecar/shipper misconfiguration.","solutions":["Configure external_labels in Prometheus config so meta.json carries Thanos labels","Pass checkExternalLabels=false only if you intentionally accept label-less blocks","Regenerate meta.json with correct thanos.labels via metadata.Meta before upload"],"exampleFix":"// before\nmeta.Thanos.Labels = map[string]string{}\n// after\nmeta.Thanos.Labels = map[string]string{\"prometheus\": \"cluster-a\", \"replica\": \"0\"}","handlingStrategy":"validation","validationCode":"meta, err := metadata.ReadFromDir(bdir)\nif err != nil { return err }\nif len(meta.Thanos.Labels) == 0 { return errors.New(\"block has no Thanos external labels\") }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Configure external_labels in Prometheus before shipping blocks","Keep sidecar/shipper versions consistent with Prometheus config","Sanity-check meta.json contents in CI for custom upload tooling"],"tags":["configuration","metadata","validation"],"backgroundTag":"empty-required-field","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"}