theonedev/onedev · error · ExplicitException

Http request failed (status: %s)

Error message

Http request failed (status: %s)

What it means

JerseyUtils.get throws ExplicitException("Http request failed (status: <status>)") when a GET returns a non-200 status but the response has no readable error message entity. The status code alone is reported because the server supplied no body.

Source

Thrown at server-core/src/main/java/io/onedev/server/util/JerseyUtils.java:44

				return String.format("Http request failed (url: %s, status code: %d)", url, status);
			}
		} else {
			return null;
		}
	}
	
	public static JsonNode get(Client client, String apiEndpoint, TaskLogger logger) {
		WebTarget target = client.target(apiEndpoint);
		Invocation.Builder builder =  target.request();
		try (Response response = builder.get()) {
			int status = response.getStatus();
			if (status != 200) {
				String errorMessage = response.readEntity(String.class);
				if (StringUtils.isNotBlank(errorMessage)) {
					throw new ExplicitException(String.format("Http request failed (url: %s, status code: %d, error message: %s)", 
							apiEndpoint, status, errorMessage));
				} else {
					throw new ExplicitException(String.format("Http request failed (status: %s)", status));
				}
			} 
			return response.readEntity(JsonNode.class);
		}
	}
	
	public static interface PageDataConsumer {
		
		void consume(List<JsonNode> pageData) throws InterruptedException;
		
	}
	
}

View on GitHub (pinned to d44925c47c)

Solutions

  1. Check the status code in the message: 401/403 -> fix credentials/permissions; 404 -> verify URL; 429 -> back off and retry; 5xx -> server-side problem.
  2. Inspect proxy/gateway logs (nginx, load balancer) since empty bodies usually mean the intermediary produced the status.
  3. Reproduce with curl -i on the same endpoint to see raw response and headers.
  4. Confirm network/firewall rules allow the outbound request from the server host.

Example fix

// before (token revoked, empty 401 body)
JsonNode node = JerseyUtils.get("https://host/api/project"); // 'Http request failed (status: 401)'
// after: refresh/reissue token before calling
String freshToken = refreshToken();
// rebuild client with freshToken, then
JsonNode node = JerseyUtils.get("https://host/api/project");
Defensive patterns

Strategy: try-catch

Try / catch

try {
    JsonNode node = JerseyUtils.get(apiEndpoint);
} catch (ExplicitException e) {
    Matcher m = Pattern.compile("status: (\\d+)").matcher(e.getMessage());
    if (m.find()) {
        int status = Integer.parseInt(m.group(1));
        // 401/403: fix auth; 404: fix url; 429/5xx: retry with backoff
    }
}

Prevention

When it happens

Trigger: Calling JerseyUtils.get(apiEndpoint) and receiving 401/403/404/429/5xx with an empty body — commonly when a proxy/gateway strips error bodies or the server returns bare status codes.

Common situations: Reverse proxies (nginx 502/503 without body), authentication failures that return empty 401s, gateway timeouts, or firewalls blocking with bare responses.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/c0752e418764f114. Report an issue: GitHub.