go-redis/redis · error
redis: EXCLUDEEMPTY is not allowed with GROUPBY
Error message
redis: EXCLUDEEMPTY is not allowed with GROUPBY
What it means
Returned (set on the cmd) by TSMRangeWithArgs/TSMRevRangeWithArgs when ExcludeEmpty is true together with GroupByLabel or Reducer. Redis does not allow EXCLUDEEMPTY alongside GROUPBY/REDUCE in TS.MRANGE; go-redis enforces this client-side. The check is options.ExcludeEmpty && (options.GroupByLabel != nil || options.Reducer != nil).
Source
Thrown at timeseries_commands.go:172
case VarP:
return "VAR.P"
case VarS:
return "VAR.S"
case Twa:
return "TWA"
case CountNaN:
return "COUNTNAN"
case CountAll:
return "COUNTALL"
default:
return ""
}
}
var (
errTSMultiAggregationGroupBy = errors.New("redis: GROUPBY is not allowed when multiple aggregators are specified")
errTSAggregationConflict = errors.New("redis: setting both Aggregator and Aggregators is not allowed; use Aggregators instead because Aggregator is deprecated")
errTSExcludeEmptyGroupBy = errors.New("redis: EXCLUDEEMPTY is not allowed with GROUPBY")
)
func formatAggregationArgs(aggregator Aggregator, aggregators []Aggregator) (string, int, error) {
if aggregator != Invalid && len(aggregators) > 0 {
return "", 0, errTSAggregationConflict
}
if len(aggregators) == 0 {
if aggregator == Invalid {
return "", 0, nil
}
aggregationArg, err := formatAggregatorArg(aggregator)
if err != nil {
return "", 0, err
}
return aggregationArg, 1, nil
}
parts := make([]string, len(aggregators))View on GitHub (pinned to 36d97525cd)
Solutions
- Disable ExcludeEmpty when using GroupByLabel or Reducer.
- If excluding empty series is essential, drop the grouping/reducer and filter empties client-side after the query.
- Validate the options combination before calling and surface a clear error to the caller.
Example fix
// before — incompatible options
opts := &redis.TSMRangeOptions{
ExcludeEmpty: true,
GroupByLabel: "host",
}
client.TSMRangeWithArgs(ctx, from, to, filters, opts)
// after — pick one
opts := &redis.TSMRangeOptions{
GroupByLabel: "host",
// ExcludeEmpty omitted (false)
} Defensive patterns
Strategy: validation
Validate before calling
func validateExcludeEmpty(o *redis.TSMRangeOptions) error {
if o.ExcludeEmpty && (o.GroupByLabel != nil || o.Reducer != nil) {
return errors.New("ExcludeEmpty cannot be used with GroupByLabel/Reducer")
}
return nil
} Try / catch
cmd := c.TSMRangeWithArgs(ctx, from, to, filters, opts)
if err := cmd.Err(); err != nil {
if err.Error() == "redis: EXCLUDEEMPTY is not allowed with GROUPBY" {
// disable ExcludeEmpty or drop grouping
}
} Prevention
- Never set ExcludeEmpty together with GroupByLabel/Reducer.
- Filter empty series client-side if both behaviors are needed.
- Document the mutually-exclusive options in your query layer.
When it happens
Trigger: Setting TSMRangeOptions.ExcludeEmpty = true while also setting GroupByLabel or Reducer. Combining empty-series filtering with label-based grouping.
Common situations: Config-driven query builders that enable all options by default. Dashboards that want both noise reduction (exclude empty) and grouping, not realizing Redis forbids the combination.
Related errors
- redis: GROUPBY is not allowed when multiple aggregators are
- redis: please enter the command to be executed
- too many arguments
- redis: Watch requires at least one key
- FT.AGGREGATE: Reduce must follow a GroupBy step
AI-assisted analysis of go-redis/redis@36d97525cd (2026-08-06).
Data as JSON: /data/errors/380f2f3f11a4196d.json.
Report an issue: GitHub.