xpipe-io/xpipe · error · IOException

Received HTTP ${statusCode} without further details

Error message

Received HTTP ${statusCode} without further details

What it means

HttpHelper.checkOrThrow converts any HTTP response with status >= 400 into an IOException. When the response body is a String and empty (or no body text is available), it throws this generic message including only the status code. It exists so failed HTTP calls never pass silently.

Source

Thrown at app/src/main/java/io/xpipe/app/util/HttpHelper.java:121

                        @Override
                        public String getDescription() {
                            return AppI18n.get("httpProxyErrorDescription");
                        }

                        @Override
                        public boolean handle(ErrorEvent event) {
                            AppPrefs.get().selectCategory("httpProxy");
                            return true;
                        }
                    }));
            throw ex;
        }

        if (res.statusCode() >= 400) {
            if (res.body() instanceof String s) {
                var msg = !s.isEmpty() ? s : "Received HTTP " + res.statusCode() + " without further details";
                throw new IOException(msg);
            } else if (res.body() instanceof byte[] b) {
                var msg = b.length > 0
                        ? new String(b, StandardCharsets.UTF_8)
                        : "Received HTTP " + res.statusCode() + " without further details";
                throw new IOException(msg);
            }
        }
    }
}

View on GitHub (pinned to d85ca821ba)

Solutions

  1. Log/check res.statusCode() to identify the failure class
  2. Verify the request URL, method, and headers are correct
  3. Add authentication or refresh credentials if the status is 401/403
  4. Retry with backoff for transient 5xx statuses; inspect server logs for 5xx

Example fix

// before: ignoring status
var res = HttpHelper.send(request);
// after: handle error statuses explicitly
var res = HttpHelper.send(request);
try {
    HttpHelper.checkOrThrow(res);
} catch (IOException e) {
    throw new IOException("request to " + res.uri() + " failed: " + e.getMessage(), e);
}
Defensive patterns

Strategy: validation

Validate before calling

if (res.statusCode() >= 400) {
    throw new IOException("HTTP " + res.statusCode() + " from " + res.uri() + " before processing");
}

Try / catch

try {
    HttpHelper.checkOrThrow(res);
} catch (IOException e) {
    if (e.getMessage().contains("Received HTTP 4")) {
        // fix request/auth
    } else {
        // retry/backoff for 5xx
    }
}

Prevention

When it happens

Trigger: Calling an HttpHelper request whose response status is >= 400 (404, 401, 500, etc.) with a String body that is empty, so no server-provided error detail exists.

Common situations: Hitting an endpoint that returns bare status codes without error bodies (e.g. load balancer 502/503, HEAD-like responses); wrong URL returning empty 404; expired auth returning empty 401.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of xpipe-io/xpipe@d85ca821ba (2026-09-06). Data as JSON: /api/errors/1d96e51f06f9ce64. Report an issue: GitHub.