You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When the Pact Broker is hosted behind a reverse proxy under a URL sub-path (context path, e.g. https://broker.example.com/pact-broker), provider verification in broker mode (consumer version selectors) fails to find pacts. The verifier requests the for-verification endpoint without the base-path prefix, gets a 404, reports "No pacts found", and — with pending enabled — passes the build having verified nothing (false green).
Direct curl to the correctly-prefixed for-verification URL returns 200 with the expected pacts, so the broker and proxy are configured correctly; the wrong URL is constructed by the verifier's HAL client. This looks like a recurrence / incomplete fix of #420.
Environment / versions
Component
Version
pact-go
2.5.0
Verifier engine (reported by broker verifiedBy.implementation)
Pact-Rust 1.3.3
libpact_ffi
as bundled by pact-go v2.5.0
Pact Broker (self-hosted)
2.119.0 (Puma 7.2.1)
Pact specification
4.0
Go
1.26.0
Reverse proxy
APISIX (behavior is generic to any proxy hosting the broker under a sub-path)
Broker deployment: served under a sub-path; PACT_BROKER_BASE_URL=https://broker.example.com/pact-broker. Reverse proxy strips the /pact-broker prefix before forwarding to the broker (broker serves at /).
Consumer publishing works (branch travels in the request body, not the URL path).
Verification via an explicit pact URL (PactURLs/PACT_URL) works end-to-end — verifies and publishes results back, because the follow-on links (publish-verification-results, branch-version PUT) are base_url-derived and correct.
What does NOT work ❌
Provider verification in broker mode (ConsumerVersionSelectors). The verifier logs the correctly-prefixed path but the actual HTTP request drops /pact-broker:
INFO pact_verifier::pact_broker: Fetching path '' from pact broker
INFO pact_verifier::pact_broker: Fetching path '/pact-broker/pacts/provider/<provider>/for-verification' from pact broker
INFO pact_verifier::pact_broker: error response for pacts for verification: Link/Resource was not found -
Request to pact broker path '/pacts/provider/<provider>/for-verification' failed: 404 Not Found.
URL: 'https://broker.example.com/pact-broker'
ERROR pact_verifier: No pacts found for provider '<provider>' matching the given consumer version selectors
in pact broker 'https://broker.example.com/pact-broker': ... failed: 404 Not Found.
URL: 'https://broker.example.com/pact-broker'
WARN pact_verifier: Ignoring no pacts error - No pacts found ...
--- PASS: TestPactProvider (1.82s) # <-- false green: verified 0 pacts
Note the discrepancy: it logs /pact-broker/pacts/.../for-verification (correct) but requests /pacts/.../for-verification (base path dropped).
Proof that the dropped-prefix URL is what 404s (i.e. the URL the verifier actually hits):
curl -s -o /dev/null -w '%{http_code}\n' -X POST \
'https://broker.example.com/pacts/provider/<provider>/for-verification' \
-H 'Content-Type: application/json' -d '{...}'
# → 404 (no route without the /pact-broker prefix)
Secondary observation (broker-side link generation)
Within the same for-verification response, the embedded pact link is base_url-correct but the collection self link omits the base path and reflects the request host:
The index and embedded links honor PACT_BROKER_BASE_URL, but the for-verification collection self link does not. (This is secondary — the verifier fails on its own request before this link is used — but may be the same root cause on the broker side.)
Steps to reproduce
Host Pact Broker behind a reverse proxy under a sub-path, e.g. https://broker.example.com/pact-broker; set PACT_BROKER_BASE_URL to that value; proxy strips the prefix to the broker.
Publish a consumer pact on a branch .
Run a pact-go v2 provider verification in broker mode:
Expected: with BrokerURL (or PACT_BROKER_BASE_URL) containing a path component, the verifier preserves that base path when requesting for-verification (as it correctly does for the index and as curl does), fetches the pacts, and verifies them.
Actual: the base path is dropped from the for-verification request → 404 → no pacts → silent pass.
Root cause hypothesis
The HAL client appears to resolve the for-verification relation against the origin (scheme+host) and discard the base-URL path — classic RFC-3986 base-URL-without-trailing-slash / context-path handling. This matches #420 ("Unable to find pacts when using pactBrokerUrl with context path"), which was reportedly addressed previously but reproduces here on Pact-Rust 1.3.3 (via pact-go 2.5.0).
Also tried, no effect: adding/removing a trailing slash on the base URL; confirming the broker honors X-Forwarded-* and PACT_BROKER_BASE_URL (verified by hitting the broker pod directly).
Workaround in use
Verify via an explicit pact URL (PactURLs) instead of the broker's for-verification flow — this bypasses the broken URL construction and works (verifies + publishes results).
Questions for maintainers
Is hosting the Pact Broker under a sub-path / context path a supported topology for provider verification, or is a broker at the root of a host required? (The reverse-proxy docs only show full-domain base URLs.)
Should the "No pacts found" outcome really resolve to a passing build under EnablePending when the cause was a transport 404 (vs. a genuine empty selector result)? The silent false-green is dangerous.
Is the for-verification collection self link expected to honor base_url's path like the index/embedded links do?
Summary
When the Pact Broker is hosted behind a reverse proxy under a URL sub-path (context path, e.g. https://broker.example.com/pact-broker), provider verification in broker mode (consumer version selectors) fails to find pacts. The verifier requests the for-verification endpoint without the base-path prefix, gets a 404, reports "No pacts found", and — with pending enabled — passes the build having verified nothing (false green).
Direct curl to the correctly-prefixed for-verification URL returns 200 with the expected pacts, so the broker and proxy are configured correctly; the wrong URL is constructed by the verifier's HAL client. This looks like a recurrence / incomplete fix of #420.
Environment / versions
Broker deployment: served under a sub-path; PACT_BROKER_BASE_URL=https://broker.example.com/pact-broker. Reverse proxy strips the /pact-broker prefix before forwarding to the broker (broker serves at /).
What works ✅
What does NOT work ❌
Provider verification in broker mode (ConsumerVersionSelectors). The verifier logs the correctly-prefixed path but the actual HTTP request drops /pact-broker:
Note the discrepancy: it logs /pact-broker/pacts/.../for-verification (correct) but requests /pacts/.../for-verification (base path dropped).
Proof that the dropped-prefix URL is what 404s (i.e. the URL the verifier actually hits):
Secondary observation (broker-side link generation)
Within the same for-verification response, the embedded pact link is base_url-correct but the collection self link omits the base path and reflects the request host:
The index and embedded links honor PACT_BROKER_BASE_URL, but the for-verification collection self link does not. (This is secondary — the verifier fails on its own request before this link is used — but may be the same root cause on the broker side.)
Steps to reproduce
Expected vs actual
Root cause hypothesis
The HAL client appears to resolve the for-verification relation against the origin (scheme+host) and discard the base-URL path — classic RFC-3986 base-URL-without-trailing-slash / context-path handling. This matches #420 ("Unable to find pacts when using pactBrokerUrl with context path"), which was reportedly addressed previously but reproduces here on Pact-Rust 1.3.3 (via pact-go 2.5.0).
Also tried, no effect: adding/removing a trailing slash on the base URL; confirming the broker honors X-Forwarded-* and PACT_BROKER_BASE_URL (verified by hitting the broker pod directly).
Workaround in use
Verify via an explicit pact URL (PactURLs) instead of the broker's for-verification flow — this bypasses the broken URL construction and works (verifies + publishes results).
Questions for maintainers