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.

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.

Appendix: 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)