From 248165c3cb3e35832872be0e3d6a1d83c1df9291 Mon Sep 17 00:00:00 2001 From: "Rodrigo Rodriguez (Pragmatismo)" Date: Wed, 22 Apr 2026 16:40:53 +0000 Subject: [PATCH] fix: Recognize 301/401/403 as reachable in embedding health check Remote APIs like Cloudflare Workers AI return 401 on /health and 301 on HEAD requests. These indicate the server IS reachable, not down. Previously only 404/405 were treated as reachable, causing all KB indexing to fail with 'Embedding server not available'. --- botserver/src/core/kb/embedding_generator.rs | 44 +++++++++++--------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/botserver/src/core/kb/embedding_generator.rs b/botserver/src/core/kb/embedding_generator.rs index 751a9550..a03aafdf 100644 --- a/botserver/src/core/kb/embedding_generator.rs +++ b/botserver/src/core/kb/embedding_generator.rs @@ -311,12 +311,12 @@ impl KbEmbeddingGenerator { Duration::from_secs(self.config.connect_timeout_seconds), self.client.get(&health_url).send() ).await { - Ok(Ok(response)) => { - let status = response.status(); - if status.is_success() { - info!("Embedding server health check passed ({})", self.config.embedding_url); - set_embedding_server_ready(true); - true + Ok(Ok(response)) => { + let status = response.status(); + if status.is_success() { + info!("Embedding server health check passed ({})", self.config.embedding_url); + set_embedding_server_ready(true); + true } else if status.as_u16() == 404 || status.as_u16() == 405 { // Server is reachable but has no /health endpoint (remote API, llama.cpp /embedding-only) // Try a HEAD request to the base URL to confirm it's up @@ -327,25 +327,31 @@ impl KbEmbeddingGenerator { ).await { Ok(Ok(_)) => { info!("Embedding server reachable at {}, marking as ready", base_url); - set_embedding_server_ready(true); - true - } + set_embedding_server_ready(true); + true + } Ok(Err(e)) => { warn!("Embedding server unreachable at {}: {}", base_url, e); - set_embedding_server_ready(false); - false - } + set_embedding_server_ready(false); + false + } Err(_) => { warn!("Embedding server probe timed out for {}", base_url); - set_embedding_server_ready(false); - false - } + set_embedding_server_ready(false); + false } - } else { - warn!("Embedding server health check returned status {}", status); - set_embedding_server_ready(false); - false } + } else if status.is_redirection() || status.as_u16() == 401 || status.as_u16() == 403 { + // Redirect (301/302) or auth-required (401/403) means the server IS reachable + // This is typical for remote APIs like Cloudflare Workers AI + info!("Embedding server reachable at {} (status {} indicates external API), marking as ready", base_url, status); + set_embedding_server_ready(true); + true + } else { + warn!("Embedding server health check returned status {}", status); + set_embedding_server_ready(false); + false + } } Ok(Err(e)) => { // Connection failed entirely — server not running or network issue