{
  "schema_version": 2,
  "id": "develop/reference/errors/all/time-series",
  "title": "Time series errors",
  "url": "https://redis.io/docs/latest/develop/reference/errors/all/time-series/",
  "summary": "Every error message that time series commands return in Redis 8.10",
  "tags": [
    "docs",
    "develop",
    "stack",
    "oss",
    "rs",
    "rc",
    "oss",
    "kubernetes",
    "clients"
  ],
  "last_updated": "2026-11-02T15:10:28+01:00",
  "page_type": "content",
  "content_hash": "bd90e264f12ce240fa477b261efe8775b67307520e6fc5a3390ccfe51b0af64c",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "These are the error messages of the [time series](https://redis.io/docs/latest/develop/data-types/timeseries) commands, such as `TS.ADD` and `TS.RANGE`. Most of them start with `ERR TSDB:`. A few start with `TSDB:` alone, and some start with `WRONGTYPE` or `NOPERM`."
    },
    {
      "id": "err-tsdb",
      "title": "ERR TSDB:",
      "role": "content",
      "text": "Most time series errors start with `ERR TSDB:`, followed by the problem. Many say that the command couldn't parse an argument, as in `ERR TSDB: Couldn't parse RETENTION`, or that two arguments can't be used together. Others say that the key doesn't exist, that it already exists, or that it isn't a time series. To fix it, compare your command with the syntax on its command page, such as [`TS.CREATE`](https://redis.io/docs/latest/commands/ts.create) or [`TS.RANGE`](https://redis.io/docs/latest/commands/ts.range).\n\n| Error message | Explanation | Returned by |\n|---|---|---|\n| `ERR TSDB: ALIGN parameter can only be used with AGGREGATION` | You passed `ALIGN` without `AGGREGATION`. Alignment only sets where aggregation buckets start, so add an `AGGREGATION` clause or remove `ALIGN`. | `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: bucketDuration must be greater than zero` | The bucket duration after the aggregator in `AGGREGATION` is 0 or negative. Pass the bucket length in milliseconds as a positive integer, as in `AGGREGATION avg 60000` for one-minute buckets. | `TS.CREATERULE`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: BUCKETTIMESTAMP flag should be the 3rd or 4th flag after AGGREGATION flag` | `BUCKETTIMESTAMP` isn't where Redis expects it: it must come right after `AGGREGATION aggregator bucketDuration`, or right after an `EMPTY` that follows them. Move it into the aggregation clause, as in `AGGREGATION avg 1000 BUCKETTIMESTAMP mid`. | `TS.CREATERULE`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: cannot accept WITHLABELS and SELECT_LABELS together` | You passed both `WITHLABELS` and `SELECTED_LABELS`, which the message calls `SELECT_LABELS`. Use `WITHLABELS` to get all labels, or `SELECTED_LABELS` followed by the label names you want, not both. | `TS.MGET`, `TS.MRANGE`, `TS.MREVRANGE` |\n| `ERR TSDB: cannot increment/decrement NaN value` | The newest sample of the series has the value `NaN`, so `TS.INCRBY` and `TS.DECRBY` have no number to change. Add a sample with a numeric value with `TS.ADD` first, then increment it. | `TS.DECRBY`, `TS.INCRBY` |\n| `ERR TSDB: CHUNK_SIZE value must be a multiple of 8 in the range [48 .. 1048576]` | The `CHUNK_SIZE` value isn't a multiple of 8 between 48 and 1048576 bytes. Use a value in that range, such as the default, 4096, which comes from `ts-chunk-size-bytes`. | `TS.ADD`, `TS.ALTER`, `TS.CREATE`, `TS.DECRBY`, `TS.INCRBY` |\n| `ERR TSDB: compaction rule does not exist` | The source series in `TS.DELETERULE` has no compaction rule that writes to the destination key you gave. Check the key order, source first, and see the rules with `TS.INFO` on the source key. | `TS.DELETERULE` |\n| `ERR TSDB: Couldn't parse AGGREGATION` | `AGGREGATION` isn't followed by an aggregator and a bucket duration, or the duration isn't an integer. Write it as `AGGREGATION aggregator bucketDuration`, with the duration in milliseconds, for example `AGGREGATION avg 60000`. | `TS.CREATERULE`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: Couldn't parse alignTimestamp` | The optional alignment timestamp, the last argument of `TS.CREATERULE`, isn't an integer of 0 or more. Pass a timestamp in milliseconds, or leave it out to align buckets to 0. | `TS.CREATERULE`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: Couldn't parse CHUNK_SIZE` | The value after `CHUNK_SIZE` isn't an integer, or it's missing. Pass the chunk size in bytes, a multiple of 8 from 48 to 1048576. | `TS.ADD`, `TS.ALTER`, `TS.CREATE`, `TS.DECRBY`, `TS.INCRBY` |\n| `ERR TSDB: Couldn't parse COUNT` | The value after `COUNT` isn't an integer. Pass the maximum number of samples or buckets to return, as a whole number of 1 or more. | `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: Couldn't parse DUPLICATE_POLICY` | `DUPLICATE_POLICY`, or `ON_DUPLICATE` in `TS.ADD`, is the last argument, with no policy after it. Add one of `BLOCK`, `FIRST`, `LAST`, `MIN`, `MAX`, or `SUM`. | `TS.ADD`, `TS.ALTER`, `TS.CREATE`, `TS.DECRBY`, `TS.INCRBY` |\n| `ERR TSDB: Couldn't parse EMPTY flag` | Redis couldn't read the `EMPTY` flag of the aggregation clause. You shouldn't normally see this; check that `EMPTY` comes right after the bucket duration or after the `BUCKETTIMESTAMP` value. | `TS.CREATERULE`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: Couldn't parse IGNORE` | `IGNORE` isn't followed by two values: a maximum time difference in milliseconds, as an integer, and a maximum value difference. Write it as `IGNORE maxTimeDiff maxValDiff`, for example `IGNORE 1000 0.5`. | `TS.ADD`, `TS.ALTER`, `TS.CREATE`, `TS.DECRBY`, `TS.INCRBY` |\n| `ERR TSDB: Couldn't parse LABELS` | One of the labels after `LABELS` has an empty name or value, or a value that contains a parenthesis or a comma. Give each label as a name and a value without those characters; `LABELS` must be the last option. | `TS.ADD`, `TS.ALTER`, `TS.CREATE`, `TS.DECRBY`, `TS.INCRBY` |\n| `ERR TSDB: Couldn't parse MAX` | The second value after `FILTER_BY_VALUE`, the maximum, isn't a number. Write it as `FILTER_BY_VALUE min max`, for example `FILTER_BY_VALUE 0 100`. | `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: Couldn't parse MIN` | The first value after `FILTER_BY_VALUE`, the minimum, isn't a number. Write it as `FILTER_BY_VALUE min max`, for example `FILTER_BY_VALUE 0 100`. | `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: Couldn't parse RETENTION` | The value after `RETENTION` isn't an integer, or it's missing. Pass the retention period in milliseconds, or 0 to keep samples forever. | `TS.ADD`, `TS.ALTER`, `TS.CREATE`, `TS.DECRBY`, `TS.INCRBY` |\n| `ERR TSDB: COUNT argument is missing` | `COUNT` is the last argument, with no number after it. Add the maximum number of samples or buckets to return, such as `COUNT 10`, or remove `COUNT`. | `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: CREATERULE requires exactly one aggregation type` | You passed a list of aggregators, such as `avg,max`, to `TS.CREATERULE`. A compaction rule writes one aggregation to its destination, so create one rule, each with its own destination key, for each aggregator. | `TS.CREATERULE` |\n| `ERR TSDB: Empty aggregation type in list` | The list of aggregators after `AGGREGATION` has an empty entry, for example `avg,,max`, a trailing comma, or an empty string. Remove the extra commas so that every entry names an aggregator. | `TS.CREATERULE`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: EMPTY flag should be the 3rd or 5th flag after AGGREGATION flag` | `EMPTY` isn't where Redis expects it: it must come right after `AGGREGATION aggregator bucketDuration`, or after the `BUCKETTIMESTAMP` value that follows them. Move it into the aggregation clause, as in `AGGREGATION avg 1000 EMPTY`. | `TS.CREATERULE`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: end alignment can only be used with explicit end timestamp` | You used `ALIGN end`, or `ALIGN +`, with `+` as the end timestamp, so there's no fixed end to align buckets to. Pass an explicit end timestamp, or align to `start` or to a timestamp instead. | `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: Error at upsert, update is not supported when DUPLICATE_POLICY is set to BLOCK mode, or either current or new value is NaN and DUPLICATE_POLICY is MAX/MIN/SUM` | A sample already exists at that timestamp, and the duplicate policy, `BLOCK` by default, rejects the new one; with `MIN`, `MAX`, or `SUM`, one value being `NaN` also fails. Use `ON_DUPLICATE` in `TS.ADD`, or change the policy with `TS.ALTER`. | `TS.ADD`, `TS.DECRBY`, `TS.INCRBY`, `TS.MADD` |\n| `ERR TSDB: EXCLUDEEMPTY is not allowed with GROUPBY` | You passed `EXCLUDEEMPTY` together with `GROUPBY` in `TS.MRANGE` or `TS.MREVRANGE`. These two options can't be combined, so remove one of them. | `TS.MRANGE`, `TS.MREVRANGE` |\n| `ERR TSDB: failed parsing labels` | A filter expression isn't valid: each must be `label=value`, `label!=value`, `label=`, `label!=`, or a list such as `label=(a,b)`. A common cause is an option placed after `FILTER`, which treats everything after it as expressions, up to `GROUPBY`. | `TS.MGET`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.QUERYINDEX`, `TS.QUERYLABELS` |\n| `ERR TSDB: Failed to retrieve aggregation class` | Redis recognized the aggregator but couldn't load its implementation. This is an internal error you shouldn't normally see; check the aggregator names after `AGGREGATION` and retry. | `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: Failed to retrieve reducer class` | Redis recognized the reducer after `REDUCE` but couldn't load its implementation. This is an internal error you shouldn't normally see; check the reducer name and retry. | `TS.MRANGE`, `TS.MREVRANGE` |\n| `ERR TSDB: FILTER given with no filter expressions` | `FILTER` is the last argument of `TS.QUERYLABELS`, with no expressions after it. Add at least one expression such as `sensor=1`, or leave out `FILTER` to search all series. | `TS.QUERYLABELS` |\n| `ERR TSDB: FILTER_BY_TS one or more arguments are missing` | `FILTER_BY_TS` isn't followed by any timestamps, or the first value after it isn't an integer of 0 or more. List the exact timestamps to keep, in milliseconds, as in `FILTER_BY_TS 1000 2000`. | `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: FILTER_BY_VALUE one or more arguments are missing` | `FILTER_BY_VALUE` needs two values after it, a minimum and a maximum, and fewer arguments follow it. Write it as `FILTER_BY_VALUE min max`, for example `FILTER_BY_VALUE 0 100`. | `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: GROUPBY is not allowed when multiple aggregators are specified` | You combined `GROUPBY` with a list of aggregators, such as `AGGREGATION avg,max`, in `TS.MRANGE` or `TS.MREVRANGE`. Use a single aggregator with `GROUPBY`, or run one query for each aggregator. | `TS.MRANGE`, `TS.MREVRANGE` |\n| `ERR TSDB: GROUPBY should always come after filter` | `GROUPBY` comes before `FILTER` in `TS.MRANGE` or `TS.MREVRANGE`. Put the filter expressions first, and end the command with `GROUPBY label REDUCE reducer`. | `TS.MRANGE`, `TS.MREVRANGE` |\n| `ERR TSDB: IGNORE arguments cannot be negative` | One of the two values after `IGNORE` is negative. Pass 0 or more for both the maximum time difference, in milliseconds, and the maximum value difference. | `TS.ADD`, `TS.ALTER`, `TS.CREATE`, `TS.DECRBY`, `TS.INCRBY` |\n| `ERR TSDB: Invalid COUNT value` | The value after `COUNT` is 0 or negative. Pass the maximum number of samples or buckets to return, as a whole number of 1 or more. | `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: invalid increase/decrease value` | The value argument of `TS.INCRBY` or `TS.DECRBY`, right after the key, isn't a number. Pass the amount to add or subtract, as in `TS.INCRBY key 5`. | `TS.DECRBY`, `TS.INCRBY` |\n| `ERR TSDB: Invalid reducer type` | The reducer after `REDUCE` isn't one that grouping supports. Use `avg`, `sum`, `min`, `max`, `range`, `count`, `countNaN`, `countAll`, `std.p`, `std.s`, `var.p`, or `var.s`; `first`, `last`, and `twa` aren't allowed. | `TS.MRANGE`, `TS.MREVRANGE` |\n| `ERR TSDB: invalid timestamp` | The timestamp isn't an integer or `*`. Pass a Unix time in milliseconds, or `*` to use the server's current time; for `TS.INCRBY` and `TS.DECRBY`, this is the value after `TIMESTAMP`. | `TS.ADD`, `TS.DECRBY`, `TS.INCRBY`, `TS.MADD` |\n| `ERR TSDB: invalid timestamp, must be a nonnegative integer` | The timestamp you passed to `TS.ADD` or `TS.MADD` is negative. Pass a Unix time in milliseconds, 0 or more, or `*` to use the server's current time. | `TS.ADD`, `TS.MADD` |\n| `ERR TSDB: invalid value` | The sample value you passed to `TS.ADD` or `TS.MADD` isn't a number. Pass the value as an integer or a decimal, such as `21.5`; `NaN` is accepted too. | `TS.ADD`, `TS.MADD` |\n| `ERR TSDB: key already exists` | The key you passed to `TS.CREATE` already exists, whatever data type it holds. Use another key name, delete the key first, or change the existing series with `TS.ALTER`. | `TS.CREATE` |\n| `ERR TSDB: missing FILTER argument` | `TS.MRANGE` and `TS.MREVRANGE` need a `FILTER` clause that selects series by their labels, and the command has none. Add `FILTER` and at least one expression such as `sensor=1` after the other options. | `TS.MRANGE`, `TS.MREVRANGE` |\n| `ERR TSDB: missing labels for filter argument` | `FILTER` in `TS.MRANGE` or `TS.MREVRANGE` has no expressions after it, before the end of the command or before `GROUPBY`. Add at least one expression such as `sensor=1`. | `TS.MRANGE`, `TS.MREVRANGE` |\n| `ERR TSDB: numkeys must be a positive integer` | The `numkeys` argument of `TS.NRANGE` or `TS.NREVRANGE`, the first one, isn't an integer of 1 or more. Pass the number of keys that follow it, as in `TS.NRANGE 2 key1 key2 - +`. | `TS.NRANGE`, `TS.NREVRANGE` |\n| `ERR TSDB: please provide at least one matcher` | Every filter expression you gave is negative, such as `label!=value` or `label=`, so none can select series on its own. Add at least one expression that matches a value, `label=value` or `label=(a,b)`. | `TS.MGET`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.QUERYINDEX`, `TS.QUERYLABELS` |\n| `ERR TSDB: reached max size for SELECT_LABELS` | You listed more than 50 label names after `SELECTED_LABELS`, which the message calls `SELECT_LABELS`. Ask for 50 labels or fewer, or use `WITHLABELS` to get all of them. | `TS.MGET`, `TS.MRANGE`, `TS.MREVRANGE` |\n| `ERR TSDB: SELECT_LABELS should have at least 1 parameter` | `SELECTED_LABELS`, which the message calls `SELECT_LABELS`, isn't followed by any label names before the next keyword, such as `FILTER`. List the label names to return right after it. | `TS.MGET`, `TS.MRANGE`, `TS.MREVRANGE` |\n| `ERR TSDB: start alignment can only be used with explicit start timestamp` | You used `ALIGN start`, or `ALIGN -`, with `-` as the start timestamp, so there's no fixed start to align buckets to. Pass an explicit start timestamp, or align to `end` or to a timestamp instead. | `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: the destination key already has a dst rule` | The destination key of `TS.CREATERULE` is itself the source of compaction rules. Rules can't be chained, so use a destination series that has no rules of its own, or compact from the original source. | `TS.CREATERULE` |\n| `ERR TSDB: the destination key already has a src rule` | The destination key of `TS.CREATERULE` already receives samples from a compaction rule, possibly this same one. Each destination can have only one source, so use a new destination series. | `TS.CREATERULE` |\n| `ERR TSDB: the key does not exist` | The time series key doesn't exist. Create it with `TS.CREATE`, or with a first `TS.ADD`, which creates the key; for `TS.CREATERULE` and `TS.DELETERULE`, both the source and the destination must exist. | `TS.ALTER`, `TS.CREATERULE`, `TS.DEL`, `TS.DELETERULE`, `TS.GET`, `TS.INFO`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: the key is not a TSDB key` | The key holds another data type, not a time series; with `TS.MADD`, a key that doesn't exist gets this error too, because `TS.MADD` doesn't create keys. Create the series with `TS.CREATE` first. | `TS.ADD`, `TS.MADD` |\n| `ERR TSDB: the number of AGGREGATION arguments must be equal to numkeys` | With more than one key, `TS.NRANGE` and `TS.NREVRANGE` need one aggregator spec per key after `AGGREGATION`, then one shared bucket duration. Give exactly `numkeys` specs, as in `TS.NRANGE 2 k1 k2 - + AGGREGATION avg max 1000`. | `TS.NRANGE`, `TS.NREVRANGE` |\n| `ERR TSDB: the source key already has a source rule` | The source key of `TS.CREATERULE` is itself the destination of another compaction rule. Rules can't be chained, so create the rule from the original source series instead. | `TS.CREATERULE` |\n| `ERR TSDB: the source key and destination key should be different` | You passed the same key as both source and destination to `TS.CREATERULE`. A compaction rule writes to a separate series, so create a destination with `TS.CREATE` and pass its name. | `TS.CREATERULE` |\n| `ERR TSDB: Timestamp is older than retention` | The sample's timestamp is further back than the series' retention period allows, counting from its newest sample, so Redis would drop it at once. Use a more recent timestamp, or increase `RETENTION` with `TS.ALTER`. | `TS.ADD`, `TS.DECRBY`, `TS.INCRBY`, `TS.MADD` |\n| `ERR TSDB: Too many aggregation types` | The list after `AGGREGATION` has more than 16 aggregators. Remove repeated entries; there are 15 aggregators in all, so each one only needs to appear once. | `TS.CREATERULE`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: Unknown aggregation type` | An aggregator after `AGGREGATION` isn't one Redis knows. Use `avg`, `sum`, `min`, `max`, `range`, `count`, `countNaN`, `countAll`, `first`, `last`, `std.p`, `std.s`, `var.p`, `var.s`, or `twa`, separated by commas to request several. | `TS.CREATERULE`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: unknown ALIGN parameter` | The value after `ALIGN` isn't `start`, `end`, `-`, `+`, or a timestamp of 0 or more. Pass one of those to set where aggregation buckets start. | `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: unknown argument, expected FILTER` | `TS.QUERYLABELS` found an argument other than `FILTER` after `LABELS`, or after `VALUES` and its label name. Start the filter expressions with `FILTER`, or leave them out to search all series. | `TS.QUERYLABELS` |\n| `ERR TSDB: unknown BUCKETTIMESTAMP parameter` | The value after `BUCKETTIMESTAMP` isn't one Redis knows. Use `start` or `-`, `end` or `+`, or `mid` or `~`, to choose which timestamp each bucket reports. | `TS.CREATERULE`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: Unknown DUPLICATE_POLICY` | The value after `DUPLICATE_POLICY`, or `ON_DUPLICATE` in `TS.ADD`, isn't a known policy. Use one of `BLOCK`, `FIRST`, `LAST`, `MIN`, `MAX`, or `SUM`. | `TS.ADD`, `TS.ALTER`, `TS.CREATE`, `TS.DECRBY`, `TS.INCRBY` |\n| `ERR TSDB: unknown ENCODING parameter` | The value after `ENCODING` isn't an encoding Redis knows. Use `COMPRESSED`, the default, or `UNCOMPRESSED` to store samples without compression. | `TS.ADD`, `TS.ALTER`, `TS.CREATE`, `TS.DECRBY`, `TS.INCRBY` |\n| `ERR TSDB: unknown subtype, must be one of LABELS\\|VALUES` | The first argument of `TS.QUERYLABELS` isn't `LABELS` or `VALUES`. Use `LABELS` to list label names, or `VALUES` followed by a label name to list that label's values. | `TS.QUERYLABELS` |\n| `ERR TSDB: When a series has compactions, deleting samples or compaction buckets beyond the series retention period is not possible` | The series has compaction rules, and the start of your `TS.DEL` range, or of a compaction bucket that contains it, is older than the newest sample's timestamp minus the series' `RETENTION`. Start the range later. | `TS.DEL` |\n| `ERR TSDB: wrong 3rd argument` | The only option `TS.GET` takes after the key is `LATEST`, and you passed something else. Remove the argument, or use `LATEST` to include the latest, still-open bucket of a compaction series. | `TS.GET` |\n| `ERR TSDB: wrong fromTimestamp` | The start timestamp of the range isn't `-` or an integer of 0 or more. Pass a Unix time in milliseconds, or `-` to start at the earliest sample. | `TS.DEL`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `ERR TSDB: wrong toTimestamp` | The end timestamp of the range isn't `+` or an integer of 0 or more. Pass a Unix time in milliseconds, or `+` to end at the latest sample. | `TS.DEL`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |"
    },
    {
      "id": "err",
      "title": "ERR",
      "role": "content",
      "text": "A few errors use the general prefix `ERR` without `TSDB:`. They include the wrong number of arguments for a command, and errors of `CONFIG SET` for the time series configuration parameters, which start with `ERR CONFIG SET failed`. Most commands also report a key of the wrong data type as `ERR WRONGTYPE`. See [`WRONGTYPE`](https://redis.io/docs/latest/develop/reference/errors/common/wrongtype).\n\n| Error message | Explanation | Returned by |\n|---|---|---|\n| `ERR CONFIG SET failed (possibly related to argument 'ts-chunk-size-bytes') - TSDB: CHUNK_SIZE value must be a multiple of 8 in the range [48 .. 1048576]` | The value you set for `ts-chunk-size-bytes` isn't a multiple of 8 between 48 and 1048576 bytes. Use a value in that range, such as the default, 4096. | `CONFIG SET` |\n| `ERR CONFIG SET failed (possibly related to argument 'ts-compaction-policy') - Invalid compaction policy: <policy>` | The value you set for `ts-compaction-policy` doesn't follow its format: rules separated by `;`, each `aggregator:bucketDuration:retention`. Each duration needs a unit, `m` (milliseconds), `s`, `M` (minutes), `h`, or `d`, as in `max:1M:1d`. | `CONFIG SET` |\n| `ERR CONFIG SET failed (possibly related to argument 'ts-duplicate-policy') - Invalid duplicate policy: <policy>` | The value you set for `ts-duplicate-policy` isn't a policy Redis knows. Use one of `BLOCK` (the default), `FIRST`, `LAST`, `MIN`, `MAX`, or `SUM`. | `CONFIG SET` |\n| `ERR CONFIG SET failed (possibly related to argument 'ts-encoding') - Invalid encoding: <encoding>` | The value you set for `ts-encoding` isn't a known encoding. Use `COMPRESSED`, the default, or `UNCOMPRESSED`. | `CONFIG SET` |\n| `` ERR CONFIG SET failed (possibly related to argument 'ts-ignore-max-val-diff') - Invalid value for `ts-ignore-max-val-diff` `` | The value you set for `ts-ignore-max-val-diff` isn't a number. Pass a number of 0 or more, such as `0.5`. | `CONFIG SET` |\n| `` ERR CONFIG SET failed (possibly related to argument 'ts-ignore-max-val-diff') - Invalid value for `ts-ignore-max-val-diff`. Value must be in the range [<min> .. <max> `` | The value you set for `ts-ignore-max-val-diff` is negative. Use 0 or more; the long number in the message is the largest double-precision value, and the message is cut off after it. | `CONFIG SET` |\n| `ERR CONFIG SET failed (possibly related to argument 'ts-num-threads') - Cannot set ts-num-threads after the LibMR worker pool has started` | The worker threads of LibMR, the library time series uses to run commands across shards, have already started, so `CONFIG SET` can't change `ts-num-threads` any more. Set it in the configuration file and restart Redis. | `CONFIG SET` |\n| `ERR wrong number of arguments for '<command>' command` | You called the command in the message with too many or too few arguments. Check its syntax; a common cause is an option without its value, such as `ENCODING` or `GROUPBY` with nothing after it. [How to fix it](https://redis.io/docs/latest/develop/reference/errors/common/err-wrong-number-of-arguments/#how-to-fix-it) | `TS.ADD`, `TS.ALTER`, `TS.CREATE`, `TS.CREATERULE`, `TS.DECRBY`, `TS.DEL`, `TS.DELETERULE`, `TS.GET`, `TS.INCRBY`, `TS.INFO`, `TS.MADD`, `TS.MGET`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.QUERYINDEX`, `TS.QUERYLABELS`, `TS.RANGE`, `TS.READ`, `TS.REVRANGE` |\n| `ERR WRONGTYPE Operation against a key holding the wrong kind of value` | The key holds a different data type, not a time series, so use a key that holds one. This error starts with `ERR`, so code that checks for the `WRONGTYPE` error code doesn't catch it. [How to fix it](https://redis.io/docs/latest/develop/reference/errors/common/wrongtype/#how-to-fix-it) | `TS.ALTER`, `TS.CREATERULE`, `TS.DECRBY`, `TS.DEL`, `TS.DELETERULE`, `TS.GET`, `TS.INCRBY`, `TS.INFO`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |"
    },
    {
      "id": "tsdb",
      "title": "TSDB:",
      "role": "content",
      "text": "A few errors start with `TSDB:` without `ERR`, so client libraries see `TSDB:` as the code. They come from `TS.ADD`, `TS.INCRBY`, `TS.DECRBY`, `TS.READ`, `TS.CREATE`, and `TS.ALTER`. For example, `TS.INCRBY` can't add a sample with a timestamp older than the newest sample, and the `BLOCK` option of [`TS.READ`](https://redis.io/docs/latest/commands/ts.read) needs valid numbers.\n\n| Error message | Explanation | Returned by |\n|---|---|---|\n| `TSDB: BLOCK milliseconds must be a non-negative integer` | One of the two values after `BLOCK` in `TS.READ` isn't an integer, or the timeout is negative; the message names the milliseconds even when `min_count` is the problem. Write it as `BLOCK milliseconds min_count`, where 0 milliseconds waits indefinitely. | `TS.READ` |\n| `TSDB: BLOCK min_count must be <= MAX_COUNT` | The `min_count` value after `BLOCK` in `TS.READ` is larger than `MAX_COUNT`, so the command could never return enough samples to unblock. Make `MAX_COUNT` at least as large as `min_count`. | `TS.READ` |\n| `TSDB: BLOCK min_count must be a positive integer` | The `min_count` value after `BLOCK` in `TS.READ` is 0 or negative. Pass the number of samples to wait for as a whole number of 1 or more, as in `BLOCK 5000 1`. | `TS.READ` |\n| `TSDB: blocking TS.READ (with BLOCK) is not allowed inside MULTI, EVAL, or a deny-blocking context` | `TS.READ` with `BLOCK` had to wait, but it ran inside `MULTI`/`EXEC`, a Lua script or function, or another context where commands can't block. Run it outside the transaction or script, or drop `BLOCK` to read without waiting. | `TS.READ` |\n| `TSDB: Couldn't parse RETENTION` | The value after `RETENTION` is negative. Pass the retention period in milliseconds, 0 or more, where 0 keeps samples forever. | `TS.ADD`, `TS.ALTER`, `TS.CREATE`, `TS.DECRBY`, `TS.INCRBY` |\n| `TSDB: invalid timestamp` | The timestamp argument of `TS.READ` isn't an integer of 0 or more, or one of `-`, `+`, and `$`. Pass a Unix time in milliseconds, `-` for all samples, `+` to start at the latest, or `$` for new samples only. | `TS.READ` |\n| `TSDB: MAX_COUNT must be a positive integer` | The value after `MAX_COUNT` in `TS.READ` isn't an integer of 1 or more. Pass the most samples you want back, or leave out `MAX_COUNT` for no limit. | `TS.READ` |\n| `TSDB: timestamp must be equal to or higher than the maximum existing timestamp` | `TS.INCRBY` and `TS.DECRBY` only work on the newest sample, and the `TIMESTAMP` you passed is older than it. Pass a timestamp equal to or later than the newest sample, or leave out `TIMESTAMP` to use the current time. | `TS.DECRBY`, `TS.INCRBY` |"
    },
    {
      "id": "noperm",
      "title": "NOPERM",
      "role": "content",
      "text": "Commands that find keys by their labels, such as `TS.MRANGE` and `TS.QUERYINDEX`, check your permission for every key that matches the filter. You get this error when your user isn't allowed to read, or write, one or more of those keys. To fix it, give the user access to the keys, or use a filter that only matches keys the user can access. See [`NOPERM`](https://redis.io/docs/latest/develop/reference/errors/common/noperm).\n\n| Error message | Explanation | Returned by |\n|---|---|---|\n| `NOPERM Multi-keys command failed. <shard_error_text>` | In a cluster, a shard refused its part of the command because your user lacks permission; the rest of the message is that shard's error. Check that the user's access control list (ACL) rules allow reading the matching keys on every shard. [How to fix it](https://redis.io/docs/latest/develop/reference/errors/common/noperm/#how-to-fix-it) | `TS.MGET`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.QUERYINDEX`, `TS.QUERYLABELS` |\n| `NOPERM the current user doesn't have the read permission to one or more keys that match the specified filter` | Your user can't read a key the command uses, despite the mention of a filter; for `TS.CREATERULE`, that's the source or destination key. Add read access to those keys in the user's access control list (ACL) rules with `ACL SETUSER`. [How to fix it](https://redis.io/docs/latest/develop/reference/errors/common/noperm/#how-to-fix-it) | `TS.CREATERULE`, `TS.NRANGE`, `TS.NREVRANGE`, `TS.RANGE`, `TS.REVRANGE` |\n| `NOPERM the current user doesn't have the write permission to one or more keys that match the specified filter` | Your user can't write to the source or destination key of `TS.CREATERULE`, despite the mention of a filter; creating a rule changes both series. Add write access to both keys in the user's access control list (ACL) rules with `ACL SETUSER`. [How to fix it](https://redis.io/docs/latest/develop/reference/errors/common/noperm/#how-to-fix-it) | `TS.CREATERULE` |\n| `NOPERM TSDB: current user doesn't have read permission to one or more keys that match the specified filter` | At least one series that matches your `FILTER` is a key your user isn't allowed to read, so the command returns nothing. Give the user read access to all matching keys, or narrow the filter to keys the user can read. [How to fix it](https://redis.io/docs/latest/develop/reference/errors/common/noperm/#how-to-fix-it) | `TS.MGET`, `TS.MRANGE`, `TS.MREVRANGE` |"
    },
    {
      "id": "wrongtype",
      "title": "WRONGTYPE",
      "role": "content",
      "text": "`TS.READ` returns this error, without `ERR` in front, when the key holds a different data type. See [`WRONGTYPE`](https://redis.io/docs/latest/develop/reference/errors/common/wrongtype).\n\n| Error message | Explanation | Returned by |\n|---|---|---|\n| `WRONGTYPE Operation against a key holding the wrong kind of value` | The key you passed to `TS.READ` holds a different data type, not a time series. Use a key that holds a time series; `TYPE` shows what a key holds. [How to fix it](https://redis.io/docs/latest/develop/reference/errors/common/wrongtype/#how-to-fix-it) | `TS.READ` |"
    },
    {
      "id": "messages-without-a-code",
      "title": "Messages without a code",
      "role": "content",
      "text": "These messages have no code. Client libraries and the error statistics of [`INFO errorstats`](https://redis.io/docs/latest/commands/info) treat the first word of the message as the code. They come from commands that read keys on several shards of a cluster, such as `TS.MGET` and `TS.MRANGE`. You get them when a shard doesn't reply in time, when the cluster changes during the command, or when you run such a command inside a transaction or a script.\n\n| Error message | Explanation | Returned by |\n|---|---|---|\n| `A multi-keys command failed because at least one shard did not reply within the given timeframe.` | In a cluster, at least one shard didn't answer this multi-shard command in time, so Redis gave up. Check that every shard is running, reachable, and not overloaded, then retry the command. | `TS.MGET`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.QUERYINDEX`, `TS.QUERYLABELS` |\n| `A multi-shard command failed because the cluster topology has changed` | The cluster's layout changed while the command was collecting results from the shards, for example during a failover or while slots were moving. Retry the command after the change completes. | `TS.MGET`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.QUERYINDEX`, `TS.QUERYLABELS` |\n| `Can not run multi sharded command inside a multi exec, lua, or when blocking is not allowed` | In a cluster, commands that read series from all shards, such as `TS.MRANGE`, can't run inside `MULTI`/`EXEC`, a Lua script or function, or anywhere else blocking isn't allowed. Run the command on its own, outside the transaction or script. | `TS.MGET`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.QUERYINDEX`, `TS.QUERYLABELS` |\n| `Multi-keys command failed. <shard_error>` | In a cluster, one of the shards returned an error while running its part of the command, and the rest of the message is that shard's error. Fix what that error describes, then retry. | `TS.MGET`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.QUERYINDEX`, `TS.QUERYLABELS` |\n| `Query requires unavailable slots` | In a cluster, the shards' replies didn't cover all hash slots, for example because some slots aren't assigned or a shard is down. Make sure every slot is served, which `CLUSTER INFO` shows, then retry. | `TS.MGET`, `TS.MRANGE`, `TS.MREVRANGE`, `TS.QUERYINDEX`, `TS.QUERYLABELS` |"
    }
  ],
  "examples": []
}
