Skip to content

PromQL: parser has wrong precedence with unary + and -, affecting offset arithmetic #16711

@MichaHoffmann

Description

@MichaHoffmann

What did you do?

Started prometheus compiled from 7370d62acfcbf08e0528c81857d165ee6ca1940b with or without the --enable-feature=promql-duration-expr feature flag and queried variants of the following:

curl -XPOST localhost:9090/api/v1/query  --data-urlencode 'query=foo offset -1m * bar'

What did you expect to see?

I did expect to see no parse errors.

What did you see instead? Under which circumstances?

I did see a parse error:

{"status":"error","errorType":"bad_data","error":"invalid parameter \"query\": 1:18: parse error: unexpected identifier \"bar\" in offset, expected number or duration"}

Its even worse, if i toggle the featureflag and query something that the parser does parse but parses wrong:

curl -XPOST localhost:9090/api/v1/query  --data-urlencode 'query=up offset -1m * 100'
{"status":"success","data":{"resultType":"vector","result":[]}}

vs

curl -XPOST localhost:9090/api/v1/query  --data-urlencode 'query=up offset (-1m) * 100'
{"status":"success","data":{"resultType":"vector","result":[{"metric":{"app":"prometheus","instance":"localhost:9090","job":"prometheus"},"value":[1749559998.482,"100"]}]}}

"up offset -1m * 100" seems to be parsed as "up offset (-1m * 100)" instead of "(up offset -1m) * 100"

System information

No response

Prometheus version

7370d62acfcbf08e0528c81857d165ee6ca1940b

Prometheus configuration file

Just used the example configuration from the repository:

# my global config
global:
  scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

# Alertmanager configuration
alerting:
  alertmanagers:
    - static_configs:
        - targets:
          # - alertmanager:9093

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - "first_rules.yml"
  # - "second_rules.yml"

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: "prometheus"

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    static_configs:
      - targets: ["localhost:9090"]
       # The label name is added as a label `label_name=<label_value>` to any timeseries scraped from this config.
        labels:
          app: "prometheus"

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions