theonedev/onedev · error · ExplicitException

Http request failed (status: %s)

Error message

Http request failed (status: %s)

What it means

The GitHub importer's get() helper throws this when the HTTP response status is not acceptable and the response does not carry the expected structured error payload (no error message could be extracted), so only the raw status is reported.

Source

Thrown at server-plugin/server-plugin-import-github/src/main/java/io/onedev/server/plugin/imports/github/ImportServer.java:548

				int status = response.getStatus();
				if (status != 200) {
					String errorMessage = response.readEntity(String.class);
					if (StringUtils.isNotBlank(errorMessage)) {
						if (errorMessage.contains("rate limit exceeded")) {
							long resetTime = Long.parseLong(response.getHeaderString("x-ratelimit-reset"))*1000L;
							logger.log("Rate limit exceeded, wait until reset...");
							try {
								Thread.sleep(resetTime + 60*1000L - System.currentTimeMillis());
								continue;
							} catch (InterruptedException e) {
								throw new RuntimeException(e);
							}
						} else {
							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);
			}
		}
	}

	TaskResult importProjects(ImportRepositories repositories, 
			ProjectImportOption option, boolean dryRun, TaskLogger logger) {
		Client client = newClient();
		try {
			Map<String, Optional<Long>> userIds = new HashMap<>();
			ImportResult result = new ImportResult();
			for (var gitHubRepository: repositories.getImportRepositories()) {
				OneDev.getInstance(TransactionService.class).run(() -> {
					try {
						String oneDevProjectPath = gitHubRepository;
						if (repositories.getParentOneDevProject() != null)

View on GitHub (pinned to d44925c47c)

Solutions

  1. Print/inspect the raw response body and status via curl against the same apiEndpoint
  2. Verify the configured GitHub API endpoint URL is correct (https://api.github.com)
  3. Check proxy/firewall settings that may intercept API traffic
  4. Retry later if GitHub is having an incident (status.github.com)

Example fix

// before
apiEndpoint = "https://github.example.internal/api/v3/repos/..."; // proxy block page
// after
apiEndpoint = "https://api.github.com/repos/...";
Defensive patterns

Strategy: retry

Validate before calling

// Reachability precheck expecting JSON:
var resp = client.target(apiEndpoint).request().get();
if (!resp.getMediaType().toString().contains("json"))
    throw new IllegalStateException("Endpoint not returning JSON: " + resp.getMediaType());

Try / catch

try { node = get(client, apiEndpoint, logger); }
catch (ExplicitException e) {
    if (e.getMessage().startsWith("Http request failed (status")) {
        // inspect raw response/proxy; retry with backoff or fix endpoint URL
    } else throw e;
}

Prevention

When it happens

Trigger: A get() call (from email(), list(), repoNode()) where response.getStatusInfo() is an error but the body lacks the expected JSON error message — e.g. empty body, HTML error page, proxy interception, or unexpected status family.

Common situations: Corporate proxy or firewall returning an HTML block page; GitHub 5xx with empty body; misconfigured API endpoint URL hitting a non-GitHub server; network appliances mangling responses.

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 theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/5c0f8b43435f7890. Report an issue: GitHub.