janhq/jan · error · UpdateError

HTTP request failed: {0}

Error message

HTTP request failed: {0}

What it means

The RequestFailed variant of UpdateError is produced via #[from] reqwest::Error whenever an HTTP request to an update-check endpoint fails at the transport level. This covers connection refused, DNS resolution failure, TLS handshake error, connection timeout (30s), and read timeout. The {0} interpolates the reqwest error's Display output.

Source

Thrown at src-tauri/src/core/updater/custom_updater.rs:31

use reqwest::Client;
use serde::{Deserialize, Serialize};
use std::time::Duration;
use thiserror::Error;

/// Secret key for HMAC signature
/// - In CI: Set JAN_SIGNING_KEY environment variable at build time
/// - In local dev: Falls back to a test key
const SECRET_KEY: &str = match option_env!("JAN_SIGNING_KEY") {
    Some(key) => key,
    None => "local-dev-test-key-not-for-production",
};

/// Timeout for HTTP requests
const REQUEST_TIMEOUT_SECS: u64 = 30;

#[derive(Debug, Error)]
pub enum UpdateError {
    #[error("HTTP request failed: {0}")]
    RequestFailed(#[from] reqwest::Error),

    #[error("Failed to parse update response: {0}")]
    ParseError(String),

    #[error("All endpoints failed")]
    AllEndpointsFailed,

    #[error("Invalid response from server: {0}")]
    InvalidResponse(String),

    #[error("No endpoints configured")]
    NoEndpointsConfigured,
}

/// Update information returned by the update check endpoint
/// Compatible with Tauri's updater format
#[derive(Debug, Clone, Serialize, Deserialize)]

View on GitHub (pinned to fad3f12a14)

Solutions

  1. Verify network connectivity and that the endpoint URL is reachable via curl.
  2. Check DNS resolution: `nslookup apps.jan.ai`.
  3. Ensure system CA certificates are current for TLS validation.
  4. If behind a proxy, configure HTTPS_PROXY env var or system proxy settings.

Example fix

# diagnostic
curl -v -H 'Accept: application/json' https://apps.jan.ai/update-check

# if TLS fails, check certs
openssl s_client -connect apps.jan.ai:443
Defensive patterns

Strategy: retry

Validate before calling

// Before checking for updates, verify network connectivity
async fn check_network(endpoint: &str) -> bool {
    reqwest::Client::builder()
        .timeout(std::time::Duration::from_secs(5))
        .build()
        .and_then(|c| c.head(endpoint).send()) // simplified
        .is_ok()
}

Try / catch

match updater.check_for_updates(endpoints, nonce, version).await {
    Ok(Some(info)) => { /* offer update */ }
    Ok(None) => { /* up to date */ }
    Err(UpdateError::RequestFailed(e)) => {
        log::warn!("Update check network error: {e}");
        // Schedule a retry with backoff
    }
    Err(other) => { log::warn!("Update check error: {other}"); }
}

Prevention

When it happens

Trigger: The update endpoint URL is unreachable (server down, DNS failure, firewall block). Network is offline. TLS certificate expired or untrusted. Connection timed out after REQUEST_TIMEOUT_SECS (30s). Proxy misconfiguration intercepting the request.

Common situations: Corporate proxy blocking apps.jan.ai. DNS resolution failing on a misconfigured network. Endpoint moved or decommissioned without redirect. Captive portal intercepting HTTPS. Clock skew causing TLS certificate validity check failure.

Related errors


AI-assisted analysis of janhq/jan@fad3f12a14 (2026-08-12). Data as JSON: /api/errors/e2c01fd0539b5612. Report an issue: GitHub.