Skip to content

Fix StringSliceCSV treating explicit empty string as a one-element list#7714

Open
pujitha24 wants to merge 1 commit into
cortexproject:masterfrom
pujitha24:auto/issue-6581
Open

Fix StringSliceCSV treating explicit empty string as a one-element list#7714
pujitha24 wants to merge 1 commit into
cortexproject:masterfrom
pujitha24:auto/issue-6581

Conversation

@pujitha24

Copy link
Copy Markdown
Contributor

Motivation:
Issue #6581 reports that setting compactor.enabled_tenants: ""
explicitly in config causes the compactor to skip every tenant,
instead of behaving like the unset/omitted case (all tenants
allowed). The compactor logs "skipping user because it is not owned
by this shard" for every real tenant.

Approach:
StringSliceCSV.Set (pkg/util/flagext/stringslicecsv.go), which
backs -compactor.enabled-tenants/-compactor.disabled-tenants and
several other CSV-list flags (alertmanager, ruler, store-gateway,
ingester, querier, distributor, ring, limits, etc.), implemented
Set as strings.Split(s, ","). Go's strings.Split("", ",")
returns [""], a one-element slice containing an empty string, not
an empty/nil slice. YAML unmarshaling for enabled_tenants: ""
calls Set(""), so EnabledTenants ends up as [""] with
len() == 1.

users.NewAllowedTenants (pkg/util/users/allowed_tenants.go) treats
len(enabled) > 0 as "only tenants in this list are allowed", so
with enabled == [""] only a tenant literally named "" is
allowed and every real tenant is rejected. This same
NewAllowedTenants helper backs the identical enabled/disabled
tenant list pattern in the compactor, alertmanager, ruler, and
store-gateway, so all four are affected identically by explicitly
empty tenant-list config, though issue #6581 only reports it for the
compactor.

Fix Set to special-case an empty input string by setting the value
to nil, matching the sibling SecretStringSliceCSV.Set, which
already special-cases s == "" this same way.

Validation:
go build ./...
go test ./pkg/util/flagext/... ./pkg/compactor/... ./pkg/util/validation/... ./pkg/util/users/... -tags "netgo slicelabels"
All pass, including new tests in pkg/util/flagext/stringslicecsv_test.go
covering direct Set("") and YAML unmarshaling of csv: "".

Before/after: with enabled_tenants: "", no tenant was ever
compacted by any compactor replica (every tenant matched
"not owned by this shard"/was filtered out before ownership was even
checked). After this fix, an explicitly empty enabled_tenants (or
disabled_tenants) behaves identically to the field being omitted:
all tenants are eligible, subject to normal ring sharding.

Fixes #6581

Signed-off-by: Pujitha Paladugu 10557236+pujitha24@users.noreply.github.com

Motivation:
Issue cortexproject#6581 reports that setting `compactor.enabled_tenants: ""`
explicitly in config causes the compactor to skip every tenant,
instead of behaving like the unset/omitted case (all tenants
allowed). The compactor logs "skipping user because it is not owned
by this shard" for every real tenant.

Approach:
`StringSliceCSV.Set` (pkg/util/flagext/stringslicecsv.go), which
backs `-compactor.enabled-tenants`/`-compactor.disabled-tenants` and
several other CSV-list flags (alertmanager, ruler, store-gateway,
ingester, querier, distributor, ring, limits, etc.), implemented
`Set` as `strings.Split(s, ",")`. Go's `strings.Split("", ",")`
returns `[""]`, a one-element slice containing an empty string, not
an empty/nil slice. YAML unmarshaling for `enabled_tenants: ""`
calls `Set("")`, so `EnabledTenants` ends up as `[""]` with
`len() == 1`.

`users.NewAllowedTenants` (pkg/util/users/allowed_tenants.go) treats
`len(enabled) > 0` as "only tenants in this list are allowed", so
with `enabled == [""]` only a tenant literally named `""` is
allowed and every real tenant is rejected. This same
`NewAllowedTenants` helper backs the identical enabled/disabled
tenant list pattern in the compactor, alertmanager, ruler, and
store-gateway, so all four are affected identically by explicitly
empty tenant-list config, though issue cortexproject#6581 only reports it for the
compactor.

Fix `Set` to special-case an empty input string by setting the value
to nil, matching the sibling `SecretStringSliceCSV.Set`, which
already special-cases `s == ""` this same way.

Validation:
  go build ./...
  go test ./pkg/util/flagext/... ./pkg/compactor/... ./pkg/util/validation/... ./pkg/util/users/... -tags "netgo slicelabels"
All pass, including new tests in pkg/util/flagext/stringslicecsv_test.go
covering direct `Set("")` and YAML unmarshaling of `csv: ""`.

Before/after: with `enabled_tenants: ""`, no tenant was ever
compacted by any compactor replica (every tenant matched
"not owned by this shard"/was filtered out before ownership was even
checked). After this fix, an explicitly empty `enabled_tenants` (or
`disabled_tenants`) behaves identically to the field being omitted:
all tenants are eligible, subject to normal ring sharding.

Fixes cortexproject#6581

Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 22, 2026 02:29

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request fixes a configuration edge case where CSV-backed string-slice flags/YAML fields (notably compactor.enabled_tenants / -compactor.enabled-tenants) treated an explicitly empty string ("") as a one-element slice containing "", which inadvertently enabled allow-list mode for a nonexistent empty tenant and caused all real tenants to be skipped.

Changes:

  • Update StringSliceCSV.Set to special-case s == "" by resetting the slice to nil instead of using strings.Split, aligning behavior with “unset/omitted” semantics.
  • Add unit tests covering both direct Set("") behavior and YAML unmarshalling of csv: "".
  • Add a CHANGELOG bugfix entry documenting the user-facing impact and resolution.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.

File Description
pkg/util/flagext/stringslicecsv.go Treat empty input string as an empty/unset list by setting the slice to nil before returning.
pkg/util/flagext/stringslicecsv_test.go Add tests to ensure empty-string inputs don’t produce [""] and YAML "" unmarshals to an empty list.
CHANGELOG.md Document the bugfix and its impact on enabled/disabled tenant CSV lists.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Tenants are getting skipp

2 participants