thanos-io/thanos · error
no external labels configured, uniquely identifying…
Error message
no external labels configured, uniquely identifying external labels must be configured; see https://thanos.io/tip/thanos/storage.md#external-labels for details.
What it means
A hard setup validation in registerBucketUploadBlocks: uploading blocks to object storage requires uniquely identifying external labels (at minimum a block 'name'-like label set), because blocks without them cannot be uniquely identified. If no --label flags are given, the command aborts before doing anything with this error.
Solutions
- Pass at least one external label, e.g. --label <key>="<value>" (commonly something like cluster or name).
- Ensure labels uniquely identify the uploader in your deployment (mirrors thanos sidecar requirements).
Example fix
// before thanos tools bucket upload --objstore.config-file=bucket.yaml ./promdata // after thanos tools bucket upload --objstore.config-file=bucket.yaml --label cluster="us-east-1" ./promdata
Defensive patterns
Strategy: validation
Validate before calling
// Shell: fail fast if labels were not provided if [ -z "$LABELS" ]; then echo "error: --label is required for bucket upload" >&2 exit 1 fi thanos tools bucket upload --objstore.config-file=bucket.yaml $LABELS ./promdata
Try / catch
if err := cmd.Run(); err != nil {
if strings.Contains(err.Error(), "no external labels configured") {
log.Fatal("pass at least one --label key=\"value\" flag")
}
} Prevention
- Bake required --label flags into wrapper scripts/crafted CLI profiles.
- Use the same unique label set as the sidecar for that Prometheus instance.
- Add CI checks that reject deployment scripts invoking upload without labels.
When it happens
Trigger: Running `thanos tools bucket upload` (upload blocks) without any --label flag, i.e. tbc.labels is empty.
Common situations: Scripting the upload tool and forgetting to pass labels used elsewhere (e.g. cluster/replica), or copying a command line that omitted labels.
Understand the failure class
Background: "--flag is required" and "must specify" CLI errors: how missing-required-flag validation works and how to fix it — this error's family across 20 libraries.
Related errors
- preparing command failed
- --receive.lazy-retrieval-max-buffered-responses must be > 0
- not uploading as no external labels are configured yet - is…
- nothing to verify. No verifiers and verifierRepairers…
- level is bigger then default set of
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/87a9fb263bc33275.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/thanos/tools_bucket.go:1465
level.Warn(logger).Log("msg", "GLOBAL COMPACTOR SHOULD __NOT__ BE RUNNING ON THE SAME BUCKET")
if err := compact.ApplyRetentionPolicyByResolution(ctx, logger, insBkt, sy.Metas(), retentionByResolution, stubCounter); err != nil {
return errors.Wrap(err, "retention failed")
}
return nil
})
}
func registerBucketUploadBlocks(app extkingpin.AppClause, objStoreConfig *extflag.PathOrContent) {
cmd := app.Command("upload-blocks", "Upload blocks push blocks from the provided path to the object storage.")
tbc := &bucketUploadBlocksConfig{}
tbc.registerBucketUploadBlocksFlag(cmd)
cmd.Setup(func(g *run.Group, logger log.Logger, reg *prometheus.Registry, _ opentracing.Tracer, _ <-chan struct{}, _ bool) error {
if len(tbc.labels) == 0 {
return errors.New("no external labels configured, uniquely identifying external labels must be configured; see https://thanos.io/tip/thanos/storage.md#external-labels for details.")
}
lset, err := parseFlagLabels(tbc.labels)
if err != nil {
return errors.Wrap(err, "unable to parse external labels")
}
if err := promclient.IsDirAccessible(tbc.path); err != nil {
return errors.Wrapf(err, "unable to access path '%s'", tbc.path)
}
confContentYaml, err := objStoreConfig.Content()
if err != nil {
return errors.Wrap(err, "unable to parse objstore config")
}
bkt, err := client.NewBucket(logger, confContentYaml, component.Upload.String(), nil)
if err != nil {
return errors.Wrap(err, "unable to create bucket")View on GitHub (pinned to 35b8b99117)