thanos-io/thanos · error

unable to parse objstore config

Error message

unable to parse objstore config

What it means

This error is returned by the `thanos tools bucket upload` command when objStoreConfig.Content() fails to produce the object-store configuration YAML. The config content loader validates and renders the --objstore.bucket.config-file (or inline config); a parse/read failure is wrapped here. The command cannot proceed to build a bucket client without valid config YAML.

Solutions

  1. Check the config file exists and is readable at the given path; fix the --objstore.bucket.config-file value
  2. Validate the YAML structure and indentation, especially the top-level provider key (e.g. type: s3) and its nested config
  3. Validate the config against the objstore provider schema docs for the thanos version in use
  4. If using env substitution, verify the variables resolve and the file is not empty

Example fix

// before (bucket.yaml)
storage:
  s3: ...
// after
# bucket.yaml
type: S3
config:
  bucket: my-bucket
  endpoint: s3.amazonaws.com
Defensive patterns

Strategy: validation

Validate before calling

data, err := os.ReadFile(cfgPath)
if err != nil {
    return fmt.Errorf("cannot read objstore config %q: %w", cfgPath, err)
}
var raw map[string]interface{}
if err := yaml.Unmarshal(data, &raw); err != nil {
    return fmt.Errorf("invalid YAML in %q: %w", cfgPath, err)
}
if _, ok := raw["type"]; !ok {
    return fmt.Errorf("objstore config missing 'type' key")
}

Prevention

When it happens

Trigger: The --objstore.bucket.config-file points to a missing or unreadable file, the YAML does not match any registered objstore provider schema, or the config was supplied via a flag with empty/malformed content.

Common situations: Config file path typo or file not mounted into a container; YAML with wrong indentation; using a provider name that is not compiled in (e.g. s3 misspelled); passing an empty file; referencing env-var interpolation that resolves to nothing.

Understand the failure class

Related errors


AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07). Data as JSON: /api/errors/855f74134f91c067. Report an issue: GitHub.

Appendix: source

Thrown at cmd/thanos/tools_bucket.go:1478

	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")
		}

		bkt = objstoretracing.WrapWithTraces(objstore.WrapWithMetrics(bkt, extprom.WrapRegistererWithPrefix("thanos_", reg), bkt.Name()))

		tbcDir, err := os.OpenRoot(tbc.path)
		if err != nil {
			runutil.CloseWithLogOnErr(logger, bkt, "bucket client")
			return errors.Wrap(err, "unable to open tbc directory")
		}

		s := shipper.New(
			bkt,
			tbcDir,

View on GitHub (pinned to 35b8b99117)