{"record":{"id":"2250b42922b71341","repo":"arduino/Arduino","slug":"incomplete-download","errorCode":null,"errorMessage":"Incomplete download","messagePattern":"Incomplete download","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"arduino-core/src/cc/arduino/utils/network/FileDownloader.java","lineNumber":266,"sourceCode":"\n      byte[] buffer = new byte[10240];\n      while (status == Status.DOWNLOADING) {\n        int read = stream.read(buffer);\n        if (read == -1)\n          break;\n\n        randomAccessOutputFile.write(buffer, 0, read);\n        setDownloaded(getDownloaded() + read);\n\n        if (Thread.interrupted()) {\n          randomAccessOutputFile.close();\n          throw new InterruptedException();\n        }\n      }\n\n      if (getDownloadSize() != null) {\n        if (getDownloaded() < getDownloadSize())\n          throw new Exception(\"Incomplete download\");\n      }\n    } finally {\n      IOUtils.closeQuietly(stream);\n    }\n  }\n\n  private void setError(Exception e) {\n    error = e;\n  }\n\n  public Exception getError() {\n    return error;\n  }\n\n  public boolean isCompleted() {\n    return status == Status.COMPLETE;\n  }\n}","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/arduino/Arduino/blob/a0df6e0e83b652c72bc78b0a1376c54d6ebc3bee/arduino-core/src/cc/arduino/utils/network/FileDownloader.java#L248-L284","documentation":"FileDownloader throws this generic Exception when the stream ends but fewer bytes than the declared download size (getDownloadSize()) were received. It guards against silently saving a truncated file as a complete download.","triggerScenarios":"readStreamCopyTo() finishes reading the connection stream (read() returned -1) while getDownloaded() < getDownloadSize(); i.e. the server closed the connection early or the content-length does not match the bytes delivered.","commonSituations":"Unstable or metered network dropping the connection mid-download; server-side truncation of large archives; proxy/CDN closing idle connections; VPN or Wi-Fi interruptions.","solutions":["Retry the download (the downloader supports resume: it reopens the connection and appends from the already-downloaded offset)","Check network stability (disable VPN/proxy, use wired connection) and retry","Verify the server actually serves the full content-length (curl and compare size)","Download the file manually and install it offline if the server keeps truncating"],"exampleFix":"// before: single attempt\ndownloader.downloadFile(url, file, false);\n// after: retry with resume\nfor (int i = 0; i < 3; i++) {\n  try { downloader.downloadFile(url, file, false); break; }\n  catch (Exception e) { if (i == 2) throw e; sleep(retryTimeout); }\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  downloader.downloadFile(url, file, false);\n} catch (Exception e) {\n  if (\"Incomplete download\".equals(e.getMessage())) {\n    // FileDownloader resumes from downloaded bytes\n    downloader.downloadFile(url, file, false); // retry resumes\n  } else throw e;\n}","preventionTips":["Run downloads on stable networks; avoid suspending the machine mid-download","Avoid proxies/VPNs known to cut long-lived connections","Check the downloaded file size against the server content-length afterward","Always retry rather than trusting a file from a failed download session"],"tags":["network","download","truncated","incomplete"],"backgroundTag":"network-request-failed","analyzedSha":"a0df6e0e83b652c72bc78b0a1376c54d6ebc3bee","analyzedAt":"2026-09-06T10:13:38.901Z","contentChangedAt":"2026-09-06T10:13:38.901Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}