vectordotdev/vector · critical

Building HTTP client failed

Error message

Building HTTP client failed

What it means

The http_client-based source (e.g. http_endpoint/http poller) calls HttpClient::new with the configured TLS and proxy settings and .expect()s success, since setup normally cannot fail. A panic with "Building HTTP client failed" means the TLS/proxy configuration produced an unrecoverable client construction error, terminating the source at startup.

Solutions

  1. Verify all TLS file paths (crt, key, ca) exist and contain valid PEM data
  2. Check the source's proxy configuration for malformed URLs
  3. Test with TLS options removed to isolate which setting breaks client construction
  4. Regenerate or re-export certificates if the key material is corrupt or mismatched

Example fix

// before (vector.yaml)
tls:
  ca_file: /etc/ssl/missing-ca.pem
// after
tls:
  ca_file: /etc/ssl/certs/ca-certificates.crt
Defensive patterns

Strategy: validation

Validate before calling

test -f "$CA_FILE" && openssl x509 -in "$CA_FILE" -noout >/dev/null && echo ok || echo 'bad TLS config'

Prevention

When it happens

Trigger: Invalid or unloadable TLS configuration (bad certificate/key files, unsupported settings) or a broken proxy configuration passed via HttpClient::new in the source's build fn, causing the expect to fire when the source task starts.

Common situations: Typo'd certificate/key paths in the source's tls options, malformed PEM content, incompatible TLS settings (e.g. bad CA bundle), proxy settings referencing unresolvable or malformed URLs.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16). Data as JSON: /api/errors/25d297f44b06e409. Report an issue: GitHub.

Appendix: source

Thrown at src/sources/util/http_client.rs:162

}

/// Calls one or more urls at an interval.
///   - The HTTP request is built per the options in provided generic inputs.
///   - The HTTP response is decoded/parsed into events by the specific context.
///   - The events are then sent to the output stream.
pub(crate) async fn call<
    B: HttpClientBuilder<Context = C> + Send + Clone,
    C: HttpClientContext + Send,
>(
    inputs: GenericHttpClientInputs,
    context_builder: B,
    mut out: SourceSender,
    http_method: HttpMethod,
) -> Result<(), ()> {
    // Building the HttpClient should not fail as it is just setting up the client with the
    // proxy and tls settings.
    let client =
        HttpClient::new(inputs.tls.clone(), &inputs.proxy).expect("Building HTTP client failed");
    let mut stream = IntervalStream::new(tokio::time::interval(inputs.interval))
        .take_until(inputs.shutdown)
        .map(move |_| stream::iter(inputs.urls.clone()))
        .flatten()
        .map(move |base_url| {
            let client = client.clone();
            let endpoint = base_url.to_string();

            let context_builder = context_builder.clone();
            let mut context = context_builder.build(&base_url);

            // Check if we need to process the URL dynamically (for updating VRL expressions)
            let url = context.process_url(&base_url).unwrap_or(base_url);

            let mut builder = match http_method {
                HttpMethod::Head => Request::head(&url),
                HttpMethod::Get => Request::get(&url),
                HttpMethod::Post => Request::post(&url),

View on GitHub (pinned to bdb87aeaa4)