RepoPilotOpen in app →

prometheus/blackbox_exporter

Blackbox prober exporter

Healthy

Healthy across the board

weakest axis
Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 1w ago
  • 24+ active contributors
  • Distributed ownership (top contributor 40% of recent commits)
Show all 6 evidence items →
  • Apache-2.0 licensed
  • CI configured
  • Tests present

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/prometheus/blackbox_exporter)](https://repopilot.app/r/prometheus/blackbox_exporter)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/prometheus/blackbox_exporter on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: prometheus/blackbox_exporter

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/prometheus/blackbox_exporter shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 1w ago
  • 24+ active contributors
  • Distributed ownership (top contributor 40% of recent commits)
  • Apache-2.0 licensed
  • CI configured
  • Tests present

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live prometheus/blackbox_exporter repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/prometheus/blackbox_exporter.

What it runs against: a local clone of prometheus/blackbox_exporter — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in prometheus/blackbox_exporter | Confirms the artifact applies here, not a fork | | 2 | License is still Apache-2.0 | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 37 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>prometheus/blackbox_exporter</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of prometheus/blackbox_exporter. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/prometheus/blackbox_exporter.git
#   cd blackbox_exporter
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of prometheus/blackbox_exporter and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "prometheus/blackbox_exporter(\\.git)?\\b" \\
  && ok "origin remote is prometheus/blackbox_exporter" \\
  || miss "origin remote is not prometheus/blackbox_exporter (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
  && ok "license is Apache-2.0" \\
  || miss "license drift — was Apache-2.0 at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "main.go" \\
  && ok "main.go" \\
  || miss "missing critical file: main.go"
test -f "prober/handler.go" \\
  && ok "prober/handler.go" \\
  || miss "missing critical file: prober/handler.go"
test -f "config/config.go" \\
  && ok "config/config.go" \\
  || miss "missing critical file: config/config.go"
test -f "prober/prober.go" \\
  && ok "prober/prober.go" \\
  || miss "missing critical file: prober/prober.go"
test -f "prober/http.go" \\
  && ok "prober/http.go" \\
  || miss "missing critical file: prober/http.go"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 37 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~7d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/prometheus/blackbox_exporter"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Blackbox Exporter is a Prometheus exporter that performs active probing of endpoints over HTTP, HTTPS, DNS, TCP, ICMP, and gRPC protocols, exposing probe success/failure and timing metrics. It enables external monitoring of service availability and response times by probing targets from the exporter's perspective, complementing Prometheus' pull-based scraping model. Single-binary monolith: config/ package handles YAML parsing and reload logic; prober implementations (http, tcp, icmp, dns, grpc) are separate but colocated in the root; main entrypoint uses kingpin/v2 for CLI flags and prometheus/client_golang for metrics export. Blackbox.yml example config and testdata/ configs document supported module types.

👥Who it's for

Site reliability engineers and DevOps teams running Prometheus monitoring who need to track endpoint availability, SSL certificate expiration, DNS resolution reliability, and network connectivity from geographically distributed probers without instrumenting the target services themselves.

🌱Maturity & risk

Production-ready and actively maintained: part of the official Prometheus GitHub organization with structured CI/CD via CircleCI and GitHub Actions, comprehensive test coverage in config/ and per-prober packages, and regular updates (visible in go.mod targeting Go 1.25.0 and recent dependency versions like prometheus/client_golang v1.23.2). Clear CHANGELOG.md and documented configuration in CONFIGURATION.md indicate mature release practices.

Low risk for core functionality but moderate dependency footprint: relies on miekg/dns, gorilla/websocket, quic-go, and google/cel-go which adds complexity. QUIC/HTTP3 support (visible in invalid-http-http3-http2*.yml configs) is relatively newer and may have edge cases. Single organization maintainer (MAINTAINERS.md suggests Prometheus community), but with standard governance and security contact in SECURITY.md.

Active areas of work

Active development on protocol features: config/testdata contains recent test cases for HTTP/3 with HTTP/2 validation (invalid-http-http3-http2*.yml), request compression reject-all-encodings handling, and DNS validation. go.mod shows recent updates to cel-go (0.27.0) and quic-go (0.59.0), indicating ongoing work on expression-based validation and QUIC support.

🚀Get running

Clone and build: git clone https://github.com/prometheus/blackbox_exporter.git && cd blackbox_exporter && make build. Run with default config: ./blackbox_exporter --config.file=blackbox.yml. Test with curl: curl 'http://localhost:9115/probe?target=google.com&module=http_2xx'.

Daily commands: make build compiles the binary (see Makefile.common). Run locally: ./blackbox_exporter --config.file=blackbox.yml --log.level=debug. Docker: docker run -v $(pwd):/config quay.io/prometheus/blackbox-exporter:latest --config.file=/config/blackbox.yml. Web UI at http://localhost:9115, probe endpoint at /probe?target=X&module=Y.

🗺️Map of the codebase

  • main.go — Entry point that initializes the exporter, loads configuration, and starts the HTTP server on port 9115.
  • prober/handler.go — Core HTTP handler that receives probe requests, dispatches to appropriate prober, and returns Prometheus metrics.
  • config/config.go — Configuration schema and validation for all probe modules (HTTP, DNS, TCP, ICMP, gRPC, WebSocket); required to understand supported probe types.
  • prober/prober.go — Interface definitions for all probe types and shared prober utilities; central abstraction for protocol-specific implementations.
  • prober/http.go — Largest and most complex prober implementation; handles HTTP/HTTPS/HTTP3 probes with redirect following, authentication, and body/header matching.
  • go.mod — Declares key dependencies like miekg/dns for DNS probing, gorilla/websocket for WebSocket support, and prometheus client libraries.

🛠️How to make changes

Add a new probe protocol

  1. Create new prober file in prober/ directory implementing the Prober interface from prober/prober.go (prober/newprotocol.go)
  2. Add configuration struct for the new protocol in config/config.go under the Module type (config/config.go)
  3. Add validation logic for the new protocol config in config/config.go (Validate method) (config/config.go)
  4. Register prober in the dispatch switch statement in prober/handler.go's GoProbe function (prober/handler.go)
  5. Add unit tests for new protocol with test cases and example configurations (prober/newprotocol_test.go)
  6. Add test YAML files for valid and invalid configurations in config/testdata/ (config/testdata/newprotocol-good.yml)

Add a new validation check to an existing prober

  1. Add validation field to the protocol config struct in config/config.go (config/config.go)
  2. Add validation logic in the protocol's Validate method in config/config.go (config/config.go)
  3. Update prober implementation in prober/protocol.go to check and record validation results in probe metrics (prober/http.go)
  4. Add test case for the new validation in the protocol's test file (prober/http_test.go)
  5. Create invalid test YAML in config/testdata/ to verify validation fails appropriately (config/testdata/invalid-protocol-newcheck.yml)

Add a new metric or label to probe results

  1. Update the probe result collection in prober/handler.go's collectResults function to include new metric (prober/handler.go)
  2. Modify protocol-specific prober in prober/protocol.go to calculate/capture the metric value (prober/http.go)
  3. Add test assertion in handler tests or protocol tests to verify metric is exported (prober/handler_test.go)

Modify configuration validation rules

  1. Update the Validate method for the relevant config struct in config/config.go (config/config.go)
  2. Add test cases in config/config_test.go for the new validation rule (config/config_test.go)
  3. Create or update invalid test YAML in config/testdata/ to cover the new validation (config/testdata/invalid-protocol-rule.yml)

🔧Why these technologies

  • Go — Compiled, single-binary deployment; excellent concurrency for parallel probes; native support for network I/O.
  • Prometheus client_golang — Native Prometheus metrics export format; standard for Prometheus ecosystem integration.
  • miekg/dns — Pure-Go DNS library; avoids cgo dependency and provides fine-grained control over DNS queries.
  • google/cel-go — Common Expression Language for flexible, safe probe validation without arbitrary code execution.
  • gRPC — Industry-standard RPC framework; health check probing via gRPC Health Checking Protocol.

⚖️Trade-offs already made

  • Single binary exporter vs. per-protocol agents

    • Why: Simplifies deployment, reduces operational complexity, and allows centralized configuration management.
    • Consequence: All probe types must run in the same process; one failure can impact multiple probe types.
  • Synchronous probe execution per request

    • Why: Simple request/response model; metrics reflect current state at query time.
    • Consequence: Slow probes (e.g., TCP timeouts) block the HTTP response; no proactive probe scheduling.
  • YAML configuration instead of API-driven

    • Why: GitOps-friendly, version-controlled, easy to understand; consistent with Prometheus ecosystem.
    • Consequence: Configuration changes require file reload; no runtime dynamic module creation.
  • Regex-based response matching over CEL expressions

    • Why: Backward compatibility and simplicity for common use cases.
    • Consequence: Limited expressiveness; complex validations require multiple regex checks.

🚫Non-goals (don't propose these)

  • Does not perform continuous background probing; only probes on-demand when Prometheus scrapes /probe endpoint.
  • Does not store historical probe data; only returns current probe results and metrics.
  • Does not include authentication/authorization; assumes deployment behind Prometheus or firewall.
  • Does not support probe result caching across requests; each request triggers a fresh probe.
  • Does not handle probe scheduling or alerting; those are Prometheus responsibilities.
  • Does not provide a web UI; metrics are text/plain Prometheus format only.

🪤Traps & gotchas

QUIC/HTTP3 requires Go 1.21+ and has version conflict constraints (see invalid-http-http3-http2.yml configs). DNS probing via miekg/dns may have platform-specific quirks with raw socket permissions (especially in containers; note Docker networking guidance in README). Config reload via config/reload.go does not gracefully shutdown in-flight probes. BrotliCompression feature (andybalholm/brotli) is optional but go.mod forces inclusion. CEL-go validation expressions (google/cel-go v0.27.0) have security implications if user-supplied; review CONFIGURATION.md for safe syntax.

🏗️Architecture

💡Concepts to learn

  • Active Probing vs. Passive Scraping — Blackbox Exporter inverts Prometheus' pull model—it pushes test traffic to targets and reports success/failure; understanding this distinction is critical for deployment topology (where exporter runs, scrape vs. probe intervals, alerting rules)
  • DNS Response Code Classification — config/config.go validates DNS probe configurations including expected response codes (NOERROR, NXDOMAIN, REFUSED, etc.); test cases in testdata/invalid-dns-*.yml show constraints on allowed combinations
  • TLS Certificate Validation and SNI — HTTP/HTTPS probers handle certificate chain verification, expiration checking, and Server Name Indication (SNI); config/config.go enforces HTTP version constraints when using HTTP/2 or HTTP/3
  • CEL (Common Expression Language) for Probe Validation — google/cel-go v0.27.0 dependency enables declarative validation rules in probe configs (e.g., status code ranges, body regex filters); understand CEL syntax to write safe, efficient probe assertions
  • ICMP Echo Request/Reply and TTL Handling — ICMP prober must respect TTL limits and handle platform-specific raw socket constraints; config/testdata/invalid-icmp-ttl*.yml validates TTL overflow detection before probe execution
  • HTTP Request/Response Body Matching with Brotli Compression — HTTP probes can decompress and regex-match response bodies; andybalholm/brotli adds Brotli codec support but invalid-http-compression-mismatch*.yml shows validation preventing misconfigurations where compression codec and expected encoding conflict
  • Config Reload with Hot-Swapping — config/reload.go implements live config reloading via SIGHUP without full restart; understanding reload semantics is critical for production operations (in-flight probe interruption, metric cardinality changes)
  • prometheus/snmp_exporter — Companion exporter in Prometheus ecosystem following same patterns (config.yml, Makefile.common, CircleCI/GitHub Actions); source of design precedents for new probe types
  • prometheus/exporter-toolkit — Shared library for TLS and basic auth (referenced in README for web.config.file format); blackbox_exporter depends on prometheus/exporter-toolkit v0.15.1 in go.mod
  • prometheus/prometheus — Parent project that scrapes /metrics endpoint from blackbox_exporter; understanding Prometheus scrape config and relabeling is essential for production deployment
  • miekg/dns — Direct dependency (v1.1.72 in go.mod) for DNS probing implementation; modifications to DNS probe logic require understanding this library's API
  • prometheus/client_golang — Core metrics library (v1.23.2); all probe_success, probe_duration_seconds, and custom metrics are exposed via this package

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive integration tests for HTTP/2 and HTTP/3 probe scenarios

The codebase has config validation files for HTTP/2 and HTTP/3 (invalid-http-http3-http2*.yml) but prober/http_test.go likely lacks end-to-end tests covering successful HTTP/2 and HTTP/3 probes with various compression and protocol negotiation scenarios. This ensures the complex protocol handling logic in prober/http.go works correctly across versions.

  • [ ] Review prober/http_test.go to identify missing test cases for HTTP/2 and HTTP/3 scenarios
  • [ ] Add test cases covering: HTTP/2 basic probe, HTTP/3 basic probe, protocol downgrade handling, incompatible compression-version combinations
  • [ ] Add test fixtures in config/testdata/ for valid HTTP/2 and HTTP/3 configurations if missing
  • [ ] Run tests with make test to ensure coverage improvement

Add missing unit tests for prober/history.go with concurrent access patterns

The history.go file exists but prober/history_test.go may have minimal coverage. Given that blackbox_exporter handles concurrent probe requests, the history tracking mechanism needs robust testing for race conditions, eviction policies, and metrics accuracy under concurrent load.

  • [ ] Review prober/history_test.go for existing test coverage
  • [ ] Add unit tests for concurrent Read/Write operations using goroutines and sync.WaitGroup
  • [ ] Add tests for history size limits, eviction of old entries, and metric accuracy
  • [ ] Run tests with go test -race ./prober to detect race conditions

Add DNS and gRPC probe end-to-end integration tests in CI workflow

The .github/workflows directory has golangci-lint.yml but there's no dedicated workflow for running integration tests that require network access (DNS/gRPC). Create a GitHub Actions workflow to spin up test DNS/gRPC servers and validate real probe scenarios, complementing unit tests in prober/dns_test.go and prober/grpc_test.go.

  • [ ] Create .github/workflows/integration-tests.yml workflow file
  • [ ] Set up test DNS server (using dnsmasq or similar) and gRPC test server as job services or containers
  • [ ] Configure workflow to run make test-integration (add target to Makefile if missing)
  • [ ] Add test cases in prober/dns_test.go and prober/grpc_test.go that require live servers (mark with build tags or skip if unavailable)
  • [ ] Ensure workflow runs on pull requests and main branch

🌿Good first issues

  • Add integration tests for HTTP/3 probe success/failure cases: config/testdata has test configs (invalid-http-http3-http2*.yml) but probers likely lack corresponding *_test.go coverage for the happy path
  • Document timeout cascade and race conditions in config/reload.go: Makefile.common and CircleCI setup suggest test infrastructure exists; current reload_test.go could expand to cover graceful shutdown of active probes
  • Add metrics for config reload latency and failure counts: prometheus/client_golang is already integrated; observe patterns in existing probers and expose reload performance data via /metrics endpoint

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 74011ff — Bump golang.org/x/net from 0.51.0 to 0.52.0 (#1561) (dependabot[bot])
  • 8f07811 — docker: add distroless image variant (#1572) (alliasgher)
  • fdebb2e — Add probe timeout metric (#1571) (SuperQ)
  • 8875370 — Use upstream docker archs (#1569) (SuperQ)
  • 0f0f2dc — Bump go.yaml.in/yaml/v2 from 2.4.3 to 2.4.4 (#1562) (dependabot[bot])
  • 186a6d9 — Update common Prometheus files (#1568) (prombot)
  • 0c9bd52 — Update common Prometheus files (#1556) (prombot)
  • 7dc1c3a — Make HTTP scheme parsing case-insensitive (#1137) (Astrarog)
  • d319389 — Bump github.com/google/cel-go from 0.26.1 to 0.27.0 (#1548) (dependabot[bot])
  • 2f13d5e — Bump google.golang.org/grpc from 1.79.1 to 1.79.3 (#1555) (dependabot[bot])

🔒Security observations

Failed to generate security analysis.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · prometheus/blackbox_exporter — RepoPilot