VictoriaMetrics Error Guide: 'missing `accountID` in the request path' — Fix Multitenant URLs
Fix VictoriaMetrics cluster 'missing accountID in the request path': use the correct /insert/<accountID>/ and /select/<accountID>/ URLs with a numeric accountID:projectID tenant.
- #victoriametrics
- #monitoring
- #troubleshooting
- #errors
Fixing errors like this? Get 500 free DevOps AI prompts
500 copy-paste AI prompts for the stack you actually run — one PDF, free.
Overview
VictoriaMetrics cluster mode is multitenant: vminsert and vmselect require a tenant identifier embedded in the request path. When a client hits the cluster with a single-node-style URL that omits the tenant, vminsert or vmselect rejects the request:
missing `accountID` in the request path; expecting /insert/<accountID>/prometheus for data ingestion
The vmselect side and the parse failure produce closely related wording:
cannot parse accountID from "prometheus": strconv.Atoi: parsing "prometheus": invalid syntax
These are configuration errors, not outages. The cluster is up and healthy; the client is simply using the wrong URL shape. Because single-node VictoriaMetrics accepts /prometheus/api/v1/write with no tenant, this bites teams migrating from single-node to cluster, or pointing a Prometheus remote_write/Grafana datasource at the cluster with a copy-pasted single-node URL.
Symptoms
- vminsert returns HTTP
400withmissing \accountID` in the request path` for every write. - vmselect returns
cannot parse accountID from "..."when a Grafana datasource queries it. - vmagent logs the 400 and buffers data it cannot deliver, so ingestion appears “stuck” while the cluster is fine.
- Metrics land in tenant
0:0unexpectedly, or a tenant’s data is “missing” because writes and reads used different accountIDs. - The exact same client config worked against single-node VictoriaMetrics but fails against the cluster.
curlto/prometheus/api/v1/writeon vminsert8480fails, but/insert/0/prometheus/api/v1/writesucceeds.
Common Root Causes
- Single-node URL against the cluster — using
http://vminsert:8480/prometheus/api/v1/write(no/insert/<accountID>/) instead of the tenant-qualified path. - Tenant path omitted on the read side — Grafana datasource URL set to
http://vmselect:8481/prometheusinstead ofhttp://vmselect:8481/select/<accountID>/prometheus. - Non-numeric accountID — putting a name where a number belongs (
/insert/prod/prometheus/...); accountID and projectID must be integers. - Malformed tenant syntax — using
/insert/0-0/or/insert/0.0/instead of theaccountID:projectIDform (0:0, or just0). - Mismatched write/read tenants — ingesting to accountID
12but querying accountID0, so the data appears absent. - Proxy or ingress stripping the path prefix — a reverse proxy rewriting
/insert/12/...down to/insert/...before it reaches vminsert.
Diagnostic Workflow
Confirm which component is rejecting the request and read the exact message:
sudo journalctl -u vminsert --since '15 min ago' | grep -i 'accountID'
sudo journalctl -u vmselect --since '15 min ago' | grep -i 'accountID'
Inspect the URL the client is actually using:
# vmagent remote-write target
ps -o cmd -C vmagent | tr ' ' '\n' | grep -i remoteWrite.url
# Prometheus remote_write config
grep -A3 remote_write /etc/prometheus/prometheus.yml
Test the correct multitenant write path against vminsert 8480 for tenant 0 (accountID 0). This should return HTTP 204:
curl -sv -XPOST 'http://<node>:8480/insert/0/prometheus/api/v1/write' --data-binary @/dev/null
# with an explicit projectID:
curl -sv -XPOST 'http://<node>:8480/insert/0:0/prometheus/api/v1/write' --data-binary @/dev/null
Test the correct read path against vmselect 8481 for the same tenant:
curl -s 'http://<node>:8481/select/0/prometheus/api/v1/query?query=up' | jq .status
# list series for tenant 0
curl -s 'http://<node>:8481/select/0/prometheus/api/v1/label/__name__/values' | jq '.data[0:10]'
Confirm the wrong (single-node style) URL reproduces the error, proving it is a path problem:
curl -s -XPOST 'http://<node>:8480/prometheus/api/v1/write' --data-binary @/dev/null
# => missing `accountID` in the request path; expecting /insert/<accountID>/prometheus ...
Verify which tenant actually holds data so read and write agree:
curl -s http://<node>:8482/metrics | grep -E 'vm_tenant_active_timeseries|vm_rows'
Example Root Cause Analysis
A team migrated from single-node VictoriaMetrics to a cluster to isolate two business units into separate tenants. They kept their existing vmagent config, whose -remoteWrite.url was http://vminsert:8480/prometheus/api/v1/write. Immediately, vmagent’s queue backed up and vminsert logged missing \accountID` in the request path; expecting /insert/
The cause was that the single-node URL has no tenant segment, but cluster vminsert mandates /insert/<accountID>/prometheus. The cluster was healthy — it was correctly refusing an ambiguous request that named no tenant.
They updated vmagent to -remoteWrite.url=http://vminsert:8480/insert/1:0/prometheus/api/v1/write for business unit 1 (accountID 1, projectID 0). Writes returned 204 and the buffer drained. Then a second, subtler problem surfaced: the Grafana datasource still pointed at http://vmselect:8481/select/0/prometheus, querying tenant 0 while the new data was landing in tenant 1. Panels were empty despite successful ingestion. Aligning the datasource to /select/1/prometheus made the data appear. The lesson: the accountID must match on both the write path (vminsert 8480) and the read path (vmselect 8481), and it must be numeric.
Prevention Best Practices
- Standardize on the tenant-qualified paths everywhere: writes to
http://vminsert:8480/insert/<accountID>/prometheus/api/v1/write, reads fromhttp://vmselect:8481/select/<accountID>/prometheus. - Use the
accountID:projectIDform explicitly (for example1:0) so the tenant is unambiguous, rather than relying on the bareaccountIDdefault. - Keep accountID and projectID numeric — map human-readable team names to integers in documentation, never in the URL.
- Ensure the write tenant and the read/datasource tenant match; audit both whenever you add a tenant.
- If a reverse proxy or ingress sits in front of the cluster, verify it preserves the
/insert/<id>/and/select/<id>/path prefixes and does not rewrite them. - On migration from single-node, update every client (vmagent, Prometheus
remote_write, Grafana datasources, import scripts) to the cluster URL shape before cutover.
Quick Command Reference
# See which component rejects the request and why
sudo journalctl -u vminsert -u vmselect --since '15m' | grep -i accountID
# Correct WRITE path (vminsert 8480), tenant 0 -> expect HTTP 204
curl -sv -XPOST 'http://<node>:8480/insert/0/prometheus/api/v1/write' --data-binary @/dev/null
# Correct READ path (vmselect 8481), tenant 0
curl -s 'http://<node>:8481/select/0/prometheus/api/v1/query?query=up' | jq .status
# Explicit accountID:projectID form
# .../insert/1:0/prometheus/api/v1/write and .../select/1:0/prometheus/...
# Reproduce the error with the wrong (single-node) URL
curl -s -XPOST 'http://<node>:8480/prometheus/api/v1/write' --data-binary @/dev/null
# Check where data actually lives
curl -s http://<node>:8482/metrics | grep vm_tenant_active_timeseries
Conclusion
missing \accountID` in the request path(and its siblingcannot parse accountID from …) is VictoriaMetrics cluster mode insisting that every request name a tenant. The cluster is healthy; the URL is wrong. Point writes at http://vminsert:8480/insert/and reads athttp://vmselect:8481/select/
Get 500 Battle-Tested DevOps AI Prompts — Free
500 battle-tested, copy-paste AI prompts engineered by a senior systems engineer — every one with fill-in placeholders and safety/back-out notes. Drop your email and it's yours.
- 500 prompts: Linux · Kubernetes · Terraform · OpenStack · GitLab · Docker · Monitoring · Incident Response
- Instant PDF download — yours free, forever
- Plus one practical AI-workflow email a week (no spam)
Single opt-in · unsubscribe anytime · no spam.