microg/GmsCore · error · RuntimeException

Overread allowed size end=

Error message

Overread allowed size end=

What it means

Corrupt-parcel guard in SafeParcelReflectionUtil.readObject: after consuming all recognized fields, the parcel's data position exceeds the end offset declared in the object header, so a field was over-read and the stream is inconsistent. The allowed end offset is appended.

Solutions

  1. Ensure writer and reader agree on the field layout (field ids, sizes, types) of the parcelled class
  2. Invalidate stored/transmitted parcels produced by an incompatible version
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at play-services-basement/src/main/java/org/microg/safeparcel/SafeParcelReflectionUtil.java:102 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06). Data as JSON: /api/errors/57a8d67224689fc0. Report an issue: GitHub.

Appendix: source

Thrown at play-services-basement/src/main/java/org/microg/safeparcel/SafeParcelReflectionUtil.java:102

        int end = SafeParcelReader.readObjectHeader(parcel);
        while (parcel.dataPosition() < end) {
            int header = SafeParcelReader.readHeader(parcel);
            int fieldId = SafeParcelReader.getFieldId(header);
            ClassDescriptor.FieldDescriptor fieldDescriptor = descriptor.fields.get(fieldId);
            if (fieldDescriptor == null) {
                Log.d(TAG, String.format("Unknown field id %d in %s, skipping.", fieldId, descriptor.tClass.getName()));
                SafeParcelReader.skip(parcel, header);
            } else {
                try {
                    readField(object, parcel, header, fieldDescriptor);
                } catch (Exception e) {
                    Log.w(TAG, String.format("Error reading field: %d of type %s in %s, skipping.", fieldId, fieldDescriptor.type, descriptor.tClass.getName()), e);
                    SafeParcelReader.skip(parcel, header);
                }
            }
        }
        if (parcel.dataPosition() > end) {
            throw new RuntimeException("Overread allowed size end=" + end);
        }
    }

    @SuppressWarnings("unchecked")
    private static Parcelable.Creator<Parcelable> getCreator(Field field) {
        Class<?> clazz = field.getType();
        if (clazz.isArray()) {
            clazz = clazz.getComponentType();
        }
        if (clazz != null && Parcelable.class.isAssignableFrom(clazz)) {
            return getCreator((Class<? extends Parcelable>) clazz);
        }
        throw new RuntimeException(clazz + " is not an Parcelable");
    }

    @SuppressWarnings("unchecked")
    public static Parcelable.Creator<Parcelable> getCreator(Class<? extends Parcelable> clazz) {
        try {

View on GitHub (pinned to 157c9d86ac)