microg/GmsCore · error · SecurityException
Access denied, missing google package permission for
Error message
Access denied, missing google package permission for
What it means
microG's PackageUtils.assertGooglePackagePermission throws this SecurityException when the calling app does not hold the org.microg.gms.EXTENDED_ACCESS permission (or is not a recognized Google-signed package) required for the requested GooglePackagePermission. It is a deliberate access-control gate: the check runs against the Binder caller, then logs and rethrows the SecurityException. The message ends with the name of the missing permission (permission.name()), though here the name rendered empty in the captured message.
Source
Thrown at play-services-base/core/src/main/java/org/microg/gms/common/PackageUtils.java:68
@Deprecated
public static boolean isGooglePackage(@NonNull Context context, @Nullable String packageName) {
if (packageName == null) return false;
return new ExtendedPackageInfo(context, packageName).isGoogleOrPlatformPackage();
}
/**
* @deprecated Extended access is a deprecated concept
*/
@Deprecated
public static boolean callerHasExtendedAccessPermission(@NonNull Context context) {
return context.checkCallingPermission("org.microg.gms.EXTENDED_ACCESS") == PackageManager.PERMISSION_GRANTED;
}
public static void assertGooglePackagePermission(@NonNull Context context, GooglePackagePermission permission) {
try {
if (!callerHasGooglePackagePermission(context, permission))
throw new SecurityException("Access denied, missing google package permission for " + permission.name());
} catch (SecurityException e) {
Log.w("ExtendedAccess", e);
throw e;
}
}
public static boolean callerHasGooglePackagePermission(@NonNull Context context, GooglePackagePermission permission) {
for (String packageCandidate : getCallingPackageCandidates(context)) {
if (new ExtendedPackageInfo(context, packageCandidate).hasGooglePackagePermission(permission)) {
return true;
}
}
// TODO: Replace with explicit permission instead of generic "extended access"
if (callerHasExtendedAccessPermission(context)) return true;
return false;
}View on GitHub (pinned to 157c9d86ac)
Solutions
- Declare <uses-permission android:name="org.microg.gms.EXTENDED_ACCESS"/> in the calling app's manifest and ensure microG's permission is installed/granted on the device.
- If the client should be exempt, make it a recognized Google package: sign it with the expected key or add its signature/package to the allowlist microG checks.
- Verify you actually need the guarded internal API; switch to the public Google Play services or microG public API surface that is not permission-gated.
- Catch SecurityException around the call and degrade gracefully rather than crashing.
Example fix
// before
gmsClient.callInternalApi(context);
// after
try {
gmsClient.callInternalApi(context);
} catch (SecurityException e) {
Log.w(TAG, "Extended microG access denied; falling back to public API", e);
gmsClient.callPublicApi(context);
} Defensive patterns
Strategy: try-catch
Validate before calling
int granted = context.checkCallingPermission("org.microg.gms.EXTENDED_ACCESS");
if (granted != PackageManager.PERMISSION_GRANTED) {
Log.w(TAG, "Caller lacks EXTENDED_ACCESS; skip guarded API");
} Type guard
boolean hasExtendedAccess(Context ctx) {
return ctx.checkCallingPermission("org.microg.gms.EXTENDED_ACCESS") == PackageManager.PERMISSION_GRANTED;
} Try / catch
try {
PackageUtils.assertGooglePackagePermission(context, permission);
doGuardedCall();
} catch (SecurityException e) {
Log.w(TAG, "Google package permission denied: " + permission, e);
fallbackToPublicApi();
} Prevention
- Declare org.microg.gms.EXTENDED_ACCESS in the client manifest.
- Prefer public play-services APIs over permission-gated internal ones.
- Keep client app signing consistent with microG's allowlist if you rely on Google-package exemption.
- Test on a device with microG installed before shipping guarded calls.
When it happens
Trigger: Calling an internal microG API guarded by assertGooglePackagePermission (e.g. from an app binding to a microG service) while the caller's UID lacks the org.microg.gms.EXTENDED_ACCESS permission and is not exempted as a Google package; also triggered when a client passes a GooglePackagePermission whose name cannot be resolved, producing a message with an empty name.
Common situations: Apps integrating with microG's extended/internal APIs instead of the public play-services surface; ROM or microG setups where a privileged client is not listed/signed as an allowed Google package; unit tests invoking the helper without granting the EXTENDED_ACCESS permission to the test caller.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Signature invalid
- suggested UID [
- suggested PID [
- UID [
- Access denied, missing google package permission or GET_ACCO
AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06).
Data as JSON: /api/errors/412fa69eecb1d6ba.
Report an issue: GitHub.