HMCL-dev/HMCL · error · IOException
Failed to download theme background: HTTP
Error message
Failed to download theme background: HTTP ${responseCode} ${uri} What it means
Thrown by downloadNetworkBackground when the HTTP response code for a theme-pack network background is not in the 2xx range. The method downloads the image to a temporary file and aborts immediately on any non-success status, propagating the code and URI in the message.
Solutions
- Open the URL in a browser to confirm the status; fix or replace stale 404/403 URLs in the manifest.
- Retry later if the server returned 5xx (transient upstream failure).
- Switch to an image hosted on a reliable HTTPS host, or bundle the image as a local asset in the pack.
- Check that any tokens embedded in the URL are still valid and not expired.
Example fix
// before
"background": { "url": "https://old.example.com/wall.png" } // 404
// after
"background": { "url": "https://cdn.example.com/assets/wall.png" } Defensive patterns
Strategy: retry
Validate before calling
// Optionally HEAD-check the URL before export:
HttpURLConnection c = (HttpURLConnection) URI.create(url).toURL().openConnection();
c.setRequestMethod("HEAD");
if (c.getResponseCode() / 100 != 2) throw new IllegalStateException("background URL not downloadable: " + c.getResponseCode()); Try / catch
try {
downloadNetworkBackground(uri, tmp);
} catch (IOException e) {
if (e.getMessage().contains("HTTP 5")) {
// transient server error: retry with backoff
} else {
// 4xx: fix or replace the URL
}
} Prevention
- Prefer stable, long-lived CDN URLs over personal or temporary links.
- Retry 5xx failures with backoff; treat 4xx as a manifest bug to fix.
When it happens
Trigger: Resolving a network background during theme-pack export/import where the server returns 404, 403, 500, etc.; NetworkUtils.resolveConnection succeeds but connection.getResponseCode() / 100 != 2.
Common situations: The image URL in the theme manifest no longer exists (404); the host blocks automated downloads (403); a redirect ends at an error page; a CDN or mirror is temporarily failing (5xx); the URL requires authentication.
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
- Unexpected file size
- Failed to download texture
- Theme background URL must be HTTP or HTTPS
- No download url is available
- Failed to download dependencies
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/282e63bc5a7a11bd.
Report an issue: GitHub.
Appendix: source
Thrown at HMCL/src/main/java/org/jackhuang/hmcl/theme/ThemePackManager.java:1543
return new ThemeBackground.Image(entryName);
} finally {
if (!success) {
try {
deleteIfExists(temporaryFile);
} catch (IOException e) {
LOG.warning("Failed to delete temporary theme-pack asset: " + temporaryFile, e);
}
}
}
}
/// Downloads one network background into a temporary file without installing it into the persistent image cache.
private static void downloadNetworkBackground(URI uri, Path outputFile) throws IOException {
HttpURLConnection connection = NetworkUtils.resolveConnection(NetworkUtils.createHttpConnection(uri));
try {
int responseCode = connection.getResponseCode();
if (responseCode / 100 != 2) {
throw new IOException("Failed to download theme background: HTTP " + responseCode + " " + uri);
}
ContentEncoding contentEncoding = ContentEncoding.fromConnection(connection);
try (InputStream input = contentEncoding.wrap(connection.getInputStream());
OutputStream output = Files.newOutputStream(outputFile)) {
IOUtils.copyTo(input, output, new byte[IOUtils.DEFAULT_BUFFER_SIZE]);
}
} finally {
connection.disconnect();
}
}
/// Returns a safe theme-pack asset file name for a downloaded network background.
private static String networkBackgroundAssetName(URI uri) {
String path = Objects.toString(uri.getPath(), "");
@Nullable Path fileNamePath = path.isBlank() ? null : Path.of(path).getFileName();
String fileName = fileNamePath != null ? fileNamePath.toString() : "";
String sanitized = sanitizePathSegment(fileName);View on GitHub (pinned to 24702dc5a0)