microg/GmsCore · error · ReadException
Expected size " + expectedSize + " got " + i + " (0x" + Inte
Error message
Expected size " + expectedSize + " got " + i + " (0x" + Integer.toHexString(i) + ")
What it means
SafeParcelReader.readExpectedSize() compares the size field read from the Parcel header with the size the field type requires (int=4, long=8, etc.) and throws a SafeParcelReader.ReadException on mismatch. It guards against corrupted or malformed Parcel data, or Parcels written with a different field layout.
Source
Thrown at play-services-basement/src/main/java/com/google/android/gms/common/internal/safeparcel/SafeParcelReader.java:49
@Deprecated
public static int readSingleInt(Parcel parcel) {
return parcel.readInt();
}
public static int readHeader(Parcel parcel) {
return parcel.readInt();
}
private static int readSize(Parcel parcel, int header) {
if ((header & 0xFFFF0000) != 0xFFFF0000)
return header >> 16 & 0xFFFF;
return parcel.readInt();
}
private static void readExpectedSize(Parcel parcel, int header, int expectedSize) {
int i = readSize(parcel, header);
if (i != expectedSize)
throw new ReadException("Expected size " + expectedSize + " got " + i + " (0x" + Integer.toHexString(i) + ")", parcel);
}
@Deprecated
public static int readStart(Parcel parcel) {
return readObjectHeader(parcel);
}
public static int readObjectHeader(Parcel parcel) {
int header = readHeader(parcel);
int size = readSize(parcel, header);
int start = parcel.dataPosition();
if (getFieldId(header) != SafeParcelable.SAFE_PARCEL_OBJECT_MAGIC)
throw new ReadException("Expected object header. Got 0x" + Integer.toHexString(header), parcel);
int end = start + size;
if ((end < start) || (end > parcel.dataSize()))
throw new ReadException("Size read is invalid start=" + start + " end=" + end, parcel);
return end;
}View on GitHub (pinned to 157c9d86ac)
Solutions
- Ensure writer and reader use the same SafeParcelable field definitions and version
- Check Parcel data integrity / re-send the Bundle
- Update the library so both sides agree on the parcel format
- Catch ReadException and treat the Parcel as invalid
Example fix
// before
MyObject o = MyObject.CREATOR.createFromParcel(parcel); // mismatched layout
// after
try {
MyObject o = MyObject.CREATOR.createFromParcel(parcel);
} catch (SafeParcelReader.ReadException e) {
Log.w(TAG, "malformed parcel", e); // treat as invalid data
} Defensive patterns
Strategy: try-catch
Validate before calling
// verify writer and reader share the same SafeParcelable class version before unmarshalling
Try / catch
try { obj = CREATOR.createFromParcel(parcel); } catch (SafeParcelReader.ReadException e) { treatAsInvalidParcel(e); } Prevention
- Keep parcel field layouts stable across versions
- Bump version fields when layouts change
- Never hand-write conflicting parcel writes
When it happens
Trigger: Unmarshalling a Parcel where a primitive field was written with a size differing from expected (e.g. an int stored as 2 bytes, or field order/types changed between writer and reader versions).
Common situations: Reading Parcels created by a different app/library version with changed field definitions; corrupted Bundle data; microG vs Google writer mismatches.
Understand the failure class
Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.
Related errors
- Expected object header. Got 0x" + Integer.toHexString(header
- Size read is invalid start=" + start + " end=" + end
- null reference
- Could not read from parcel file descriptor
- ParcelableKeyValue.key must be > 0
AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06).
Data as JSON: /api/errors/2ad9b3fd4f969631.
Report an issue: GitHub.