microg/GmsCore · error · IllegalStateException

Could not read from parcel file descriptor

Error message

Could not read from parcel file descriptor

What it means

createTargetBitmap wraps any IOException raised while reading the bitmap bytes from the ParcelFileDescriptor in an IllegalStateException('Could not read from parcel file descriptor', e). This means the descriptor exists but the underlying pipe/temp file could not be read to completion (length fields or pixel data failed).

Source

Thrown at play-services-base/src/main/java/com/google/android/gms/common/data/BitmapTeleporter.java:78

            if (parcelFileDescriptor == null) {
                throw new NullPointerException("null reference");
            }
            DataInputStream dataInputStream = new DataInputStream(new ParcelFileDescriptor.AutoCloseInputStream(parcelFileDescriptor));
            try {
                try {
                    byte[] bArr = new byte[dataInputStream.readInt()];
                    int readInt = dataInputStream.readInt();
                    int readInt2 = dataInputStream.readInt();
                    Bitmap.Config valueOf = Bitmap.Config.valueOf(dataInputStream.readUTF());
                    dataInputStream.read(bArr);
                    close(dataInputStream);
                    ByteBuffer wrap = ByteBuffer.wrap(bArr);
                    Bitmap createBitmap = Bitmap.createBitmap(readInt, readInt2, valueOf);
                    createBitmap.copyPixelsFromBuffer(wrap);
                    this.targetBitmap = createBitmap;
                    this.isParceled = true;
                } catch (IOException e) {
                    throw new IllegalStateException("Could not read from parcel file descriptor", e);
                }
            } catch (Throwable th) {
                close(dataInputStream);
                throw th;
            }
        }
        return this.targetBitmap;
    }

    public final void setTargetDirectory(File file) {
        if (file == null) {
            throw new NullPointerException("Cannot set null temp directory");
        }
        this.targetDirectory = file;
    }

    private static void close(Closeable closeable) {
        try {

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Read/createTargetBitmap in the same process lifetime and before any cleanup of the temp directory used at parcel time.
  2. Set a valid, writable temp directory via setTargetDirectory(new File(context.getCacheDir(), "bitmaps")) so the temp file persists for the read.
  3. Inspect the cause exception to distinguish premature EOF vs filesystem errors; if premature EOF, re-transmit the bitmap.
  4. Retry the whole parcel/transfer round-trip; the current payload is unrecoverable.

Example fix

// before
Bitmap bmp = teleporter.createTargetBitmap(); // IllegalStateException on I/O failure

// after
try {
    Bitmap bmp = teleporter.createTargetBitmap();
} catch (IllegalStateException e) {
    Log.w(TAG, "Bitmap transfer failed, re-sending", e.getCause());
    resendBitmap(originalBitmap);
}
Defensive patterns

Strategy: try-catch

Validate before calling

ParcelFileDescriptor fd = getDescriptorIfPresent(teleporter);
if (fd == null || !fd.getFileDescriptor().valid()) {
    Log.w(TAG, "Descriptor invalid; re-transfer needed");
}

Type guard

boolean canReadDescriptor(ParcelFileDescriptor fd) {
    return fd != null && fd.getFileDescriptor() != null && fd.getFileDescriptor().valid();
}

Try / catch

try {
    return teleporter.createTargetBitmap();
} catch (IllegalStateException e) {
    Log.w(TAG, "Failed to read bitmap from descriptor", e.getCause());
    retryTransferOnce();
    return null;
}

Prevention

When it happens

Trigger: The AutoCloseInputStream hits EOF early because the producer closed the pipe or the process died; the temp file backing the descriptor was deleted before reading; corrupted/short data written during parceling; I/O errors on storage holding the temp directory.

Common situations: Passing a BitmapTeleporter across processes and reading it after the sender finished/crashed; a full or cleaned temp directory (targetDirectory) removed between write and read; large bitmaps truncated by dead binder transactions.

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 microg/GmsCore@157c9d86ac (2026-09-06). Data as JSON: /api/errors/8f9eb2bb409bf26f. Report an issue: GitHub.