Prometheus Error Guide: 'found multiple scrape configs with job name' Duplicate Job
Fix Prometheus 'found multiple scrape configs with job name' errors: locate colliding job_names across included files, dedupe scrape configs, and validate with promtool.
- #prometheus-monitoring
- #troubleshooting
- #errors
- #configuration
Exact Error Message
Two scrape configs sharing a job_name fail the config load with a precise message:
ts=2026-06-27T11:21:09.402Z caller=main.go:1183 level=error msg="Error loading config (--config.file=/etc/prometheus/prometheus.yml)" file=/etc/prometheus/prometheus.yml err="found multiple scrape configs with job name \"node\""
promtool reports the same failure:
$ promtool check config /etc/prometheus/prometheus.yml
Checking /etc/prometheus/prometheus.yml
FAILED: found multiple scrape configs with job name "node"
On a live reload it returns HTTP 400:
$ curl -s -XPOST http://localhost:9090/-/reload
failed to reload config: couldn't load configuration (--config.file=/etc/prometheus/prometheus.yml): found multiple scrape configs with job name "node"
What the Error Means
Every entry under scrape_configs (and every file pulled in via scrape_config_files) must have a unique job_name. The job_name becomes the job label on all series from that config and is the primary key Prometheus uses to track a scrape pool. When two configs declare the same name, Prometheus cannot tell which pool a series belongs to, so it rejects the entire config at load time. Like all config errors, this fails the whole file — at startup the process won’t boot; on reload the previous config is kept and HTTP 400 is returned.
This is distinct from two targets producing the same series (an ingestion-time out of order problem). Here the collision is at the config level, caught before any scrape runs.
Common Causes
- Two
scrape_configsentries sharejob_name— usually copy-paste, leaving both blocks named"node". - An included file plus inline config collide —
scrape_config_filespulls in a file definingjob_name: nodewhileprometheus.ymlalso defines it inline. file_sdandstatic_configscollision — a job usingfile_sd_configsis duplicated by a second static job under the same name.- Glob in
scrape_config_filesmatches the same job twice — two files in the glob both define the samejob_name. - Helm / operator
additionalScrapeConfigsduplicating a default job — your chart values add a job namednodeorkubernetes-podsthat the chart already ships. - Templated config rendering the same name twice — a loop in a Jinja/envsubst template emitting duplicate
job_namevalues.
How to Reproduce the Error
Define the same job_name in two places:
# /etc/prometheus/prometheus.yml
global:
scrape_interval: 15s
scrape_config_files:
- /etc/prometheus/scrape.d/*.yml
scrape_configs:
- job_name: "node"
static_configs:
- targets: ["10.0.0.11:9100"]
# /etc/prometheus/scrape.d/node.yml
scrape_configs:
- job_name: "node" # collides with the inline job above
static_configs:
- targets: ["10.0.0.12:9100"]
promtool check config /etc/prometheus/prometheus.yml
# -> FAILED: found multiple scrape configs with job name "node"
Diagnostic Commands
List every job_name across the main file and all included scrape files, then find duplicates:
grep -rhoE '^\s*-?\s*job_name:\s*.*' /etc/prometheus/prometheus.yml /etc/prometheus/scrape.d/ \
| sed -E 's/.*job_name:\s*//; s/["'"'"']//g' \
| sort | uniq -d
node
Validate the merged config (this is what catches the collision authoritatively):
promtool check config /etc/prometheus/prometheus.yml
Inspect the currently loaded config to see which jobs the running server already has:
curl -s http://localhost:9090/api/v1/status/config | jq -r '.data.yaml' | grep -E 'job_name'
Confirm the reload result and read the log:
curl -s -o /dev/stderr -w '\nHTTP %{http_code}\n' -XPOST http://localhost:9090/-/reload
journalctl -u prometheus --no-pager | grep -iE 'multiple scrape configs|Error loading config' | tail -10
For Kubernetes operator setups, check the rendered secret rather than your values file:
kubectl -n monitoring get secret prometheus-k8s -o jsonpath='{.data.prometheus\.yaml\.gz}' \
| base64 -d | gunzip | grep -E 'job_name'
Step-by-Step Resolution
-
Find the duplicate with the
grep | sort | uniq -done-liner above. It lists everyjob_namedefined more than once across all included files. -
Decide: merge or rename. If both blocks scrape the same logical fleet, merge their targets into one job:
scrape_configs: - job_name: "node" static_configs: - targets: ["10.0.0.11:9100", "10.0.0.12:9100"] -
If they are genuinely different fleets, give each a distinct name:
scrape_configs: - job_name: "node-prod" static_configs: - targets: ["10.0.0.11:9100"] - job_name: "node-staging" static_configs: - targets: ["10.0.0.12:9100"] -
Resolve inline vs included collisions. If
scrape_config_filesalready provides the job, remove the inline duplicate (or vice versa). Keep each job defined in exactly one file. -
Fix operator/Helm duplicates. If your
additionalScrapeConfigsre-declares a default job, rename it or remove it. Better, model the target as aServiceMonitor/PodMonitorso the operator owns the job and avoids hand-written collisions entirely:apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: node-exporter namespace: monitoring spec: selector: matchLabels: { app: node-exporter } endpoints: - port: metrics -
Validate, reload, confirm:
promtool check config /etc/prometheus/prometheus.yml \ && curl -s -XPOST http://localhost:9090/-/reload \ && curl -s http://localhost:9090/api/v1/status/config | jq -r '.data.yaml' | grep job_name
Prevention and Best Practices
- Run
promtool check configin CI; it deterministically catches duplicatejob_namebefore deploy. - Keep one job per file when using
scrape_config_files, and name the file after the job to make collisions visually obvious. - Never copy a scrape block without changing its
job_name; treatjob_nameas a unique key. - In Kubernetes, prefer
ServiceMonitor/PodMonitoroveradditionalScrapeConfigsso the operator guarantees uniqueness. - Add a pre-commit hook running the
grep ... | uniq -dcheck across your scrape directory. - The free incident assistant can scan a multi-file scrape layout and report which files declare the same job; see more under Prometheus and monitoring.
Related Errors
- Config reload failed / HTTP 400 — the general
Error loading configfamily; duplicatejob_nameis one specific case. - Invalid rule group / parse error — the rule-file equivalent of a load-time rejection.
out of order sample— what you get after the config loads if two distinct jobs still produce identical series.
Frequently Asked Questions
Can two scrape configs ever share a job_name?
No. job_name must be globally unique across prometheus.yml and every file in scrape_config_files. Duplicates reject the whole config.
My duplicate is across two files — why does grep on prometheus.yml alone miss it?
Because the collision is between an inline job and one pulled in via scrape_config_files. Grep across the main file and the included directory together.
Should I merge the jobs or rename them?
Merge when both blocks scrape the same logical fleet (combine their targets). Rename when they are different fleets that happen to share a copied name.
How do I find the duplicate in a Helm/operator setup?
Decode the rendered Prometheus secret (prometheus.yaml.gz) and grep job_name there. Your values file may look clean while the chart’s defaults plus your additionalScrapeConfigs collide after rendering.
Does this error stop the whole server? At startup, yes — the process exits. On reload, the running config is kept and you get HTTP 400, so the server keeps scraping with the last good config until you fix and reload.
Download the Free 500-Prompt DevOps AI Toolkit
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.