floci-io/floci · error · AwsException

ModelErrorException

ModelErrorException

Error message

Failed to reach proxy backend: {}

What it means

The HTTP call to the Bedrock proxy backend failed with a non-timeout exception — connection refused, unknown host, DNS failure, or SSL error. Mapped to ModelErrorException with HTTP 424 (Failed Dependency), since Floci is healthy but its upstream is not.

Source

Thrown at src/main/java/io/github/hectorvent/floci/services/bedrockruntime/backend/ProxyBackend.java:94

        String requestBody;
        try {
            requestBody = objectMapper.writeValueAsString(openAiRequest);
        } catch (Exception e) {
            throw new AwsException("InternalServerException", "Failed to serialize proxy request: " + e.getMessage(), 500);
        }
        builder.POST(HttpRequest.BodyPublishers.ofString(requestBody));

        long start = System.nanoTime();
        HttpResponse<String> response;
        try {
            response = httpClient.send(builder.build(), HttpResponse.BodyHandlers.ofString());
        } catch (HttpTimeoutException e) {
            LOG.warnv("Bedrock proxy backend timed out: modelId={0}, url={1}, error={2}", modelId, uri, e.getMessage());
            throw new AwsException("ModelTimeoutException", "Proxy backend timed out: " + e.getMessage(), 408);
        } catch (Exception e) {
            LOG.warnv("Bedrock proxy backend call failed: modelId={0}, url={1}, error={2}", modelId, uri, e.getMessage());
            throw new AwsException("ModelErrorException", "Failed to reach proxy backend: " + e.getMessage(), 424);
        }
        long latencyMs = (System.nanoTime() - start) / 1_000_000;

        if (response.statusCode() >= 300) {
            LOG.warnv("Bedrock proxy backend returned HTTP {0}: {1}", response.statusCode(), response.body());
            throw new AwsException("ModelErrorException",
                    "Proxy backend returned HTTP " + response.statusCode() + ": " + truncate(response.body(), 512),
                    424);
        }

        JsonNode openAiResponse;
        try {
            openAiResponse = objectMapper.readTree(response.body());
        } catch (Exception e) {
            throw new AwsException("ModelErrorException", "Proxy backend returned malformed JSON: " + e.getMessage(), 424);
        }

        return BedrockOpenAiTranslator.toBedrockResponse(objectMapper, openAiResponse, latencyMs);

View on GitHub (pinned to 62ff490619)

Solutions

  1. Verify the upstream is reachable: curl <proxy-url>/chat/completions from the Floci host/container
  2. In Docker, use host.docker.internal (or the service name) instead of localhost
  3. Match the scheme to the listener: http:// for local plain-HTTP servers

Example fix

# before
FLOCI_SERVICES_BEDROCK_RUNTIME_PROXY_URL=http://localhost:11434   # inside a container
# after
FLOCI_SERVICES_BEDROCK_RUNTIME_PROXY_URL=http://host.docker.internal:11434
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight from where Floci runs:
// curl -sf "$PROXY_URL/chat/completions" -d '{}' or a TCP check on host:port

Try / catch

try {
    converse(req);
} catch (ModelErrorException e) { // 424
    runDiagnostics(proxyUrl); // reachability + DNS check, then surface actionable error
}

Prevention

When it happens

Trigger: The proxy URL points at a service that is down (connection refused), a wrong port, an unresolvable hostname, or a TLS mismatch (https against a plain-HTTP endpoint).

Common situations: Ollama/LLaMA.sh/local gateway not started or listening on a different port; Docker networking (localhost inside a container is not the host); typo in the hostname.

Related errors


AI-assisted analysis of floci-io/floci@62ff490619 (2026-08-14). Data as JSON: /api/errors/9cbf0cc4937794df. Report an issue: GitHub.