thanos-io/thanos · error

query-frontend.org-id-header and…

Error message

query-frontend.org-id-header and query-frontend.tenant-header cannot be used together

What it means

Thanos query-frontend rejects using --query-frontend.org-id-header together with --query-frontend.tenant-header. The tenant header flag supersedes the deprecated org-id header, so specifying both is ambiguous and treated as a configuration conflict. This is a deliberate validation in runQueryFrontend.

Solutions

  1. Remove the --query-frontend.org-id-header flag and keep only --query-frontend.tenant-header.
  2. If org-id-header is still needed (legacy), remove --query-frontend.tenant-header instead.
  3. Update Helm/manifest values so only one of the two flags is set.
  4. Plan migration to tenant-header as org-id-header is slated for removal.

Example fix

// before
args:
  - --query-frontend.org-id-header=X-Scope-OrgID
  - --query-frontend.tenant-header=X-Scope-Tenant
// after
args:
  - --query-frontend.tenant-header=X-Scope-Tenant
Defensive patterns

Strategy: validation

Validate before calling

const (
  orgID  = "--query-frontend.org-id-header"
  tenant = "--query-frontend.tenant-header"
)
if hasFlag(orgID) && hasFlag(tenant) {
  return errors.New("use either org-id-header or tenant-header, not both")
}

Prevention

When it happens

Trigger: Starting query-frontend with both --query-frontend.org-id-header (or repeated org-id flags) and --query-frontend.tenant-header set to non-default values.

Common situations: Migrating multi-tenancy setups where ops added the new tenant-header flag but forgot to remove the old org-id-header flag from the deployment manifest.

Understand the failure class

Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.

Related errors


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

Appendix: source

Thrown at cmd/thanos/query_frontend.go:259

func runQueryFrontend(
	g *run.Group,
	logger log.Logger,
	reg *prometheus.Registry,
	tracer opentracing.Tracer,
	httpLogOpts []logging.Option,
	cfg *queryFrontendConfig,
	comp component.Component,
) error {
	tenantHeaderProvided := cfg.TenantHeader != "" && cfg.TenantHeader != tenancy.DefaultTenantHeader
	// If tenant header is set and different from the default tenant header, add it to the list of org id headers.
	// In this case we don't need to add the tenant header to `cfg.ForwardHeaders` because tripperware will modify
	// the request, renaming the tenant header to the default tenant header, before the header propagation logic runs.
	// TODO: This should be removed once the org id header is fully removed in Thanos.
	if tenantHeaderProvided {
		// If tenant header is provided together with the org id header, error out.
		if len(cfg.orgIdHeaders) != 0 {
			return errors.New("query-frontend.org-id-header and query-frontend.tenant-header cannot be used together")
		}

		cfg.orgIdHeaders = append(cfg.orgIdHeaders, cfg.TenantHeader)
	}

	// Temporarily manually adding the default tenant header into the list of headers to forward and org id headers.
	// This facilitates the transition from org id to tenant id with minimal amount of changes.
	cfg.ForwardHeaders = append(cfg.ForwardHeaders, tenancy.DefaultTenantHeader)
	// TODO: This should be removed once the org id header is fully removed in Thanos.
	cfg.orgIdHeaders = append(cfg.orgIdHeaders, tenancy.DefaultTenantHeader)

	queryRangeCacheConfContentYaml, err := cfg.QueryRangeConfig.CachePathOrContent.Content()
	if err != nil {
		return err
	}
	if len(queryRangeCacheConfContentYaml) > 0 {
		cacheConfig, err := queryfrontend.NewCacheConfig(logger, queryRangeCacheConfContentYaml)
		if err != nil {

View on GitHub (pinned to 35b8b99117)