APK shows corrupted file when installing on an Android display

6 min read · Published November 6, 2026

An APK that reports corrupted file during install on an Android display failed to parse, and the file is the suspect: a truncated download or Windows' hidden block mark explains the refusal, especially when an older build installs while the newest one will not. Re-download, compare bytes and digest, clear the mark, install.

A commercial display that refuses a sideloaded APK with a "corrupted file" message is almost never a bad display. The message comes from the package installer on the display: it opened the file and could not read it. Two causes cover nearly every case. The download stopped before the end and left the package incomplete, or Windows attached its hidden download mark to the file. The tell that separates a file problem from a panel problem is simple: an older build installs on the same display while the newest one refuses. Work the checks below in order. They take minutes and they settle the question. If your screen is one of ours and you want to skip APK installs entirely, the signage player guide covers the loading paths that need no APK at all.

What the "corrupted file" message means

An APK is a ZIP archive with Android's manifest, resources and native libraries inside. Before anything installs, the package manager parses the archive. The ZIP index that lists every entry sits at the end of the file, so a download that stops before the end still shows a normal file in Explorer, but the installer reads no index and reports the package invalid. That is the wording Android's own install-failure documentation uses for a parse error: the package is considered invalid, and it may be corrupt or not packaged correctly.

The second cause leaves every byte untouched. When a browser saves a file, Windows attaches a hidden stream named Zone.Identifier beside it, recording where the file came from. Microsoft documents the Unblock-File command as the way to remove it. Because the stream sits beside the file, it changes no byte of the APK itself; clear the mark on every APK you push and you take the most common Windows-side cause off the table.

Symptoms and what each points to

  • Corruption reported the moment install starts. The package cannot be parsed. A truncated download is the first suspect, the Windows mark the second.
  • A compatibility message instead of a corruption message. The package asks for something the display lacks, such as an Android release or a processor architecture. The file is intact, and no re-download will change the answer.
  • INSTALL_FAILED_UPDATE_INCOMPATIBLE, only on top of an existing install. The installed build was signed with a different key than the new one. The documented remedy is to uninstall the existing copy with adb uninstall, or to ship the update signed with the same key.
  • An older build installs, the newest refuses. The newest download is the suspect, not the display. Verify the file with the checks below; if a verified copy still refuses, install the older build first and upgrade in place.
  • The app installs and launches, then video plays black. Nothing was corrupt. That is a codec question, and it has its own writeup: Android signage player shows a black screen on video.

The checks in order

  1. Fetch a fresh copy straight from the publisher. Not a mirror, not a copy that has been through a chat app. The publisher's page is also where the size and the digest for the next steps come from.
  2. Compare byte counts. The publisher states the build's size; the file's Properties dialog in Windows shows yours. Published size minus local size is the number of missing bytes. Any result above 0 bytes means the copy is truncated: discard it and fetch again.
  3. Compare the digest when the publisher prints one. SHA-256 is the usual choice and writes its result as 64 hexadecimal characters. Compute it on your copy and compare all 64. One different character means the copy differs from the published file.
  4. Clear the Windows mark. Run Unblock-File on the file, or open the file's Properties page and clear the Unblock box. Both remove the same Zone.Identifier mark.
  5. Push with adb install. Wait for the success line before you move on.
  6. If the refusal is the update error, uninstall first. Run adb uninstall on the package, then install again. An in-place upgrade across different signing keys is refused by design.
  7. If a verified, unblocked copy still refuses cold, check the architecture. An APK that ships its native libraries in 32-bit form only will not install on hardware that accepts 64-bit only. If the package is your own build, fix the architecture list before you ship it; cross-compiling C/C++ for an Android board without an APK is its own exercise and lives under the same rules.

Example: a 55-inch display refuses the newest player build

The case: a 55-inch commercial display, UHD at 3840 x 2160 with a 500-nit panel, running its built-in Android and driven by a remote control. Build R403 of the signage player is installed and working. Build R404, release 4.0.4, was downloaded to a Windows PC, pushed over ADB, and refused with "corrupted file".

The inputs, and where each comes from: the display specification and the two build numbers come from the case; the byte count comes from Properties read against the publisher's stated size; the digest comes from the publisher's SHA-256 line; the mark comes from Windows' Zone.Identifier stream.

The rule in words: the installer refuses a package it cannot parse. A copy missing bytes from the tail cannot parse, because the ZIP index lives at the tail. A marked file may parse and still be refused. So check size, then digest, then mark, then install.

The arithmetic:

  • Missing bytes equals published size minus local size, and the pass mark is 0 bytes. The fresh R404 copy lands at exactly the published size, so 0 bytes are missing and it passes. Any positive result, even 1 byte, discards the copy.
  • The digest check compares 256 bits of SHA-256 output, and each hexadecimal digit carries 4 bits: 256 bits / 4 bits per digit = 64 characters to compare. The fresh copy matches on all 64.
  • The mark check passes after one Unblock-File run. The stream never changed the byte count, which is why the size check on its own cannot catch it.

The result: the verified copy installs with adb install on the first try, and the working R403 installation upgrades in place to R404. On a display in this state the first R404 download was the fault; the panel needs nothing, no service call and no replacement.

The decision it leads to: discard any copy that misses the published size by even 1 byte or misses one of the 64 digest characters, and fetch again; if a fully verified copy still refuses as an upgrade, adb uninstall the R403 build, install clean, and check the package's 32-bit and 64-bit libraries before ordering hardware.

The decision

Recommendation: for any sideloaded player APK on a commercial display, run the checks in this order before you blame the panel: a fresh download from the publisher, a byte-size comparison with a discard threshold of more than 0 bytes missing, all 64 digest characters when one is published, Unblock-File on the copy, then adb install. If install still refuses as an upgrade, adb uninstall the old build and install clean, and check the package's 32-bit and 64-bit libraries before you order anything.

After a successful install, power-cycle the display once and watch the app come up on its own; the settings that make that happen are in Android signage app startup for a single-purpose display. Pushing to a module with no screen attached uses the same ADB path; provisioning embedded modules with no display attached walks through it. If your goal is a lobby or counter screen that plays images and video with no installer work at all, the player software that ships with our panel-mount displays loads files from microSD or USB, so there is no APK to fetch and nothing to truncate.

One more path worth naming: the displays we sell ship with the player included and no subscription, so the common notice-board install needs no sideload at all; if you would rather run your own Android app on one, the same checks apply. The player section lists what the included software is designed to do.

Questions

Does unblocking an APK change the file itself?

No. The mark lives in a hidden stream named Zone.Identifier beside the file, and unblocking deletes only that stream. The APK's byte count and its digest are identical before and after, so the size and digest checks give the same result either way. Remember that every fresh download picks up a new mark, so clearing it is a per-copy step: verify a new download, then unblock that copy again before the push.

The publisher states no size and prints no digest. How do I check my download then?

Download the same build a second time on another computer or another network and compare the two byte counts in Properties. Two independent copies that agree to the byte catch the common truncated-download case, though they cannot catch an identical bad copy served twice from one source. If both copies refuse to install, the question moves from the transfer to the package or the display.

Why does the same APK install on one display and not another?

Differences between the displays explain it. One may accept only 64-bit native libraries while the APK ships 32-bit versions only. One may run an older Android release than the build targets. One may still hold an earlier install signed with a different key, which blocks the update until it is uninstalled. Once the file checks pass, the file is rarely the difference.

Planning information, not legal or engineering advice. Rules differ by place: check codes and permits with your local authority and your licensed trades.

Keep reading

Build your signAsk for a quote