lingochamp/FileDownloader · error · FileDownloadHttpException
response code error: , request headers: response headers
Error message
response code error: %d, request headers: %s response headers: %s
What it means
FileDownloadHttpException is thrown by DownloadLaunchRunnable.handleTrialConnectResult when the server's HTTP response code is not acceptable for the trial/redirect connection (not 206 Partial Content or 200 OK). It carries the HTTP status code plus the full request and response headers so the developer can diagnose the server-side rejection. This is the library's way of surfacing that the remote server refused or mishandled the download request.
Solutions
- Log/inspect the request and response headers attached to the exception to see exactly how the server rejected the request
- Verify the URL is still valid and returns the file directly (test with curl -I)
- Check whether the server honors Range requests; disable resume/trial download (FileDownloadProperties isTrialCancelled or remove range headers) if it returns 416
- Add required authentication headers/cookies to the request via FileDownloadListener addHeader or ConnectTask header setup
- Retry on 5xx with backoff; fix server-side issue or use a mirror URL
Example fix
// before: downloading an expired pre-signed URL
FileDownloader.getImpl().create(url).setPath(path).start();
// after: refresh the URL and add required headers before downloading
String freshUrl = refreshSignedUrl(url);
FileDownloader.getImpl().create(freshUrl)
.addHeader("Authorization", token)
.setPath(path)
.start(); Defensive patterns
Strategy: try-catch
Validate before calling
HttpURLConnection c = (HttpURLConnection) new URL(url).openConnection();
c.setRequestMethod("HEAD");
int code = c.getResponseCode();
if (code != 200 && code != 206) throw new IllegalStateException("URL not downloadable, code=" + code); Try / catch
try {
FileDownloader.getImpl().create(url).setPath(path).start(listener);
} catch (FileDownloadHttpException e) {
// e.getCode(), e.getRequestHeader(), e.getResponseHeader() for diagnostics
Log.e(TAG, "download failed with HTTP " + ((FileDownloadHttpException) e).getCode(), e);
} Prevention
- HEAD-check the URL before starting the download
- Keep signed URLs refreshed and short-lived tokens valid for the download duration
- Confirm the server supports Range requests if resuming is expected
- Attach required auth headers to the FileDownloader request
When it happens
Trigger: The server responds to the download (or 'Accept-Ranges' trial) request with a status code other than HTTP 200/206 — e.g. 403 Forbidden, 404 Not Found, 416 Range Not Satisfiable, 5xx server errors, or a redirect loop — after FileDownloader has opened the HttpURLConnection.
Common situations: URL points to a page that returns 404/403 instead of a file; CDN or server rejects Range requests (416); expired signed URLs (S3 pre-signed links returning 403); server requiring auth cookies/headers not supplied; proxy/firewall returning HTML error pages.
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
- Connection failed with request
- the download runnable must not be null!
- The file is too large to store, breakpoint in bytes
- Task[ ] can't start the download runnable, because this…
- fetched length[ ] != content length[ ], range[ , ) offset[…
AI-assisted analysis of lingochamp/FileDownloader@6237a8cac1 (2026-09-08).
Data as JSON: /api/errors/d27dbceb1ecf4243.
Report an issue: GitHub.
Appendix: source
Thrown at library/src/main/java/com/liulishuo/filedownloader/download/DownloadLaunchRunnable.java:571
redirectedUrl = connectTask.getFinalRedirectedUrl();
if (acceptPartial || onlyFromBeginning) {
// update model
String fileName = null;
if (model.isPathAsDirectory()) {
// filename
fileName = FileDownloadUtils.findFilename(connection, model.getUrl());
}
isChunked = (totalLength == TOTAL_VALUE_IN_CHUNKED_RESOURCE);
// callback
statusCallback.onConnected(isResumeAvailableOnDB && acceptPartial,
totalLength, newEtag, fileName);
} else {
throw new FileDownloadHttpException(code,
requestHeader, connection.getResponseHeaderFields());
}
}
private void realDownloadWithSingleConnection(final long totalLength)
throws IOException, IllegalAccessException {
// connect
final ConnectionProfile profile;
if (!acceptPartial) {
model.setSoFar(0);
profile = ConnectionProfile.ConnectionProfileBuild
.buildBeginToEndConnectionProfile(totalLength);
} else {
profile = ConnectionProfile.ConnectionProfileBuild
.buildToEndConnectionProfile(model.getSoFar(), model.getSoFar(),
totalLength - model.getSoFar());
}View on GitHub (pinned to 6237a8cac1)