Loki 3.5.0 — /loki/api/v1/delete returns “query not set” even though query works in /query

Hi everyone,
I’m facing an issue with the log delete API in Grafana Loki 3.5.0.

When I use the /loki/api/v1/query endpoint, my queries work perfectly fine.
However, when I try to delete logs using the /loki/api/v1/delete endpoint with the same query, I get the following response:
query not set

Setup Details

  • Loki Version: 3.5.0

  • Deployment: Kubernetes (single binary)

  • Storage Backend: MinIO (S3 compatible)


What Works

:white_check_mark: Querying logs:

curl -G "http://<loki-url>:3100/loki/api/v1/query" \
  --data-urlencode 'query={app="nginx"}'

This returns the expected log results.


What Fails

:cross_mark: Deleting logs:

curl -X POST "http://<loki-url>:3100/loki/api/v1/delete" \
  -H "Content-Type: application/json" \
  -d '{"start":"2025-10-09T00:00:00Z","end":"2025-10-09T23:59:00Z","query":"{app=\"nginx\"}"}'

Response:

query not set

There’s no delete activity or error trace visible in the Loki pod logs.

Expected Behavior

Loki should accept the delete request and return a valid request_id or delete confirmation message.

Actual Behavior
The delete API rejects the request with query not set, even though the same query works for normal querying.

this is my loki config file and I can see the logs in Minio buckets

auth_enabled: false



server:

  http_listen_port: 3100

  grpc_listen_port: 9095

  log_level: info



ingester:

  chunk_idle_period: 30s

  chunk_block_size: 262144

  chunk_retain_period: 1m

  wal:

    dir: /data/loki/wal

  lifecycler:

    ring:

      kvstore:

        store: memberlist

      replication_factor: 1



limits_config:

  allow_structured_metadata: false

  deletion_mode: filter-and-delete 

  reject_old_samples: true

  reject_old_samples_max_age: 168h

  max_entries_limit_per_query: 5000

  retention_period: 4380h

  max_query_length: 4380h

  max_query_parallelism: 8

  split_queries_by_interval: 1h

  allow_deletes: true



schema_config:

  configs:

    - from: 2025-01-01

      store: boltdb-shipper

      object_store: s3

      schema: v13

      index:

        prefix: index\_

        period: 24h



storage_config:

  boltdb_shipper:

    active_index_directory: /data/loki/boltdb-shipper-active

    cache_location: /data/loki/boltdb-shipper-cache

    cache_ttl: 24h

  aws:

    endpoint: http://monitoring-minio.monitoring.svc.cluster.local:9000

    bucketnames: protectionlog

    access_key_id: minioadmin

    secret_access_key: minioadmin

    region: us-east-1

    s3forcepathstyle: true

    insecure: true



table_manager:

  retention_deletes_enabled: true

  retention_period: 4380h



compactor:

  working_directory: /data/loki/boltdb-shipper-compactor

  retention_enabled: true

  delete_request_store: s3

  delete_request_cancel_period: 5m

  retention_delete_delay: 0s

  compaction_interval: 10s

  apply_retention_interval: 10s

@tonyswumac @yosiasz Please help here
Thanks in advance…! let me know if any other information required.

and please confirm Is delete via API supported in 3.5.0, or is there an alternate method to delete logs programmatically?

If not, what’s the recommended way to delete logs via API

I don’t personally use the delete endpoint, so I could be wrong. But perhaps try breaking your URL parts like you did with the query API call? Something like:

curl -X POST "http://<loki-url>:3100/loki/api/v1/delete" \
  --data-urlencode "start=2025-10-09T00:00:00Z" \
  --data-urlencode "end=2025-10-09T23:59:00Z" \
  --data-urlencode "query={app=\"nginx\"}"