MuntashirAkon/AppManager · error · IOException

Couldn't fully read data

Error message

Couldn't fully read data

What it means

readFullyOrThrow is a helper that loops on InputStream.read until the requested buffer is completely filled. If the stream returns <= 0 bytes before the buffer is full (EOF or stream error), it throws IOException("Couldn't fully read data"). This guards fixed-size header reads in the ADB backup protocol from silently proceeding with partial data.

Source

Thrown at app/src/main/java/io/github/muntashirakon/AppManager/backup/adb/AndroidBackupHeader.java:340

    @NonNull
    private static String readHeaderLine(@NonNull InputStream in) throws IOException {
        int c;
        StringBuilder buffer = new StringBuilder(80);
        while ((c = in.read()) >= 0) {
            if (c == '\n') {
                break;   // consume and discard the newlines
            }
            buffer.append((char) c);
        }
        return buffer.toString();
    }

    private static void readFullyOrThrow(InputStream in, byte[] buffer) throws IOException {
        int offset = 0;
        while (offset < buffer.length) {
            int bytesRead = in.read(buffer, offset, buffer.length - offset);
            if (bytesRead <= 0) {
                throw new IOException("Couldn't fully read data");
            }
            offset += bytesRead;
        }
    }

    /**
     * Generates {@link SecretKey} instance from given parameters and returns it's checksum.
     * <p>
     * Current implementation returns the key in its primary encoding format.
     *
     * @param algorithm - key generation algorithm.
     * @param pwBytes   - password.
     * @param salt      - salt.
     * @param rounds    - number of rounds to run in key generation.
     * @return Hex representation of the generated key, or null if generation failed.
     */
    @NonNull
    public static byte[] makeKeyChecksum(String algorithm, byte[] pwBytes, byte[] salt, int rounds)

View on GitHub (pinned to 0152f468fc)

Solutions

  1. Retry the backup operation and ensure the device stays connected until `adb backup` completes
  2. Verify the .ab file is not truncated: compare its size with the expected header + payload, re-create the backup if corrupt
  3. Check that the ADB backup flow (password confirmation dialog on device) was fully completed
  4. If parsing a file, open it via FileInputStream rather than a socket and confirm file length >= header size

Example fix

// before
in.read(buffer); // assumes single read fills buffer / no completeness check
// after
readFullyOrThrow(in, buffer); // throws IOException instead of silently using partial header
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure the source supplies at least the expected header bytes
if (available < expectedHeaderLength) throw new IOException("Source too short for backup header");

Type guard

static boolean hasEnoughBytes(InputStream in, int needed) throws IOException {
    return in.available() >= needed; // heuristic pre-check; readFullyOrThrow remains authoritative
}

Try / catch

try {
    AndroidBackupHeader.read(in);
} catch (IOException e) {
    if ("Couldn't fully read data".equals(e.getMessage())) {
        // treat as truncated/corrupt backup: abort and re-create the backup
    }
}

Prevention

When it happens

Trigger: Reading the Android backup header over the ADB local socket when the stream ends prematurely: `adb backup` aborts before sending the full header, the peer closes the socket, or the backup file/socket supplies fewer bytes than the expected header length.

Common situations: User confirms backup on device but cancels immediately; encrypted backup password dialog interaction breaks the stream; truncated or corrupted .ab backup file being parsed; device disconnected mid-handshake.

Understand the failure class

Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.

Related errors


AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12). Data as JSON: /api/errors/1996adad2b6f7925. Report an issue: GitHub.