microg/GmsCore · error · NullPointerException

No service provided

Error message

No service provided

What it means

GcmNetworkManager.validateService throws NullPointerException when the service class name passed in is null. Every public API that routes work to a GcmTaskService (schedule, cancelTask, cancelAllTasks) must supply a concrete service component; a null name is unusable.

Source

Thrown at play-services-gcm/src/main/java/com/google/android/gms/gcm/GcmNetworkManager.java:232

        if (!packageExists(GMS_PACKAGE_NAME)) return null;
        Intent scheduleIntent = new Intent(ACTION_SCHEDULE);
        scheduleIntent.setPackage(GMS_PACKAGE_NAME);
        scheduleIntent.putExtra("app", PendingIntent.getBroadcast(context, 0, new Intent(), 0));
        return scheduleIntent;
    }

    private boolean packageExists(String packageName) {
        try {
            PackageManager pm = context.getPackageManager();
            pm.getPackageInfo(packageName, 0);
            return true;
        } catch (PackageManager.NameNotFoundException e) {
            return false;
        }
    }

    private void validateService(String serviceName) {
        if (serviceName == null) throw new NullPointerException("No service provided");
        Intent taskIntent = new Intent(ACTION_TASK_READY);
        taskIntent.setPackage(context.getPackageName());
        PackageManager pm = context.getPackageManager();
        List<ResolveInfo> serviceResolves = pm.queryIntentServices(taskIntent, 0);
        if (serviceResolves == null || serviceResolves.isEmpty())
            throw new IllegalArgumentException("No service found");
        for (ResolveInfo info : serviceResolves) {
            if (serviceName.equals(info.serviceInfo.name)) return;
        }
        throw new IllegalArgumentException("Service not supported.");
    }
}

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Pass a concrete GcmTaskService subclass: GcmNetworkManager.cancelTask(tag, MyTaskService.class).
  2. Ensure the constant/config holding the service class name is initialized before use.
  3. Verify the service exists in AndroidManifest.xml with the ACTION_TASK_READY intent filter.

Example fix

// before
String svc = flavorConfig.get("taskService"); // null
gcmNetworkManager.cancelTask(tag, svc); // NPE

// after
Class<? extends GcmTaskService> svc = MyTaskService.class;
gcmNetworkManager.cancelTask(tag, svc);
Defensive patterns

Strategy: type-guard

Validate before calling

if (serviceClass == null) {
    throw new IllegalStateException("GcmTaskService class must be configured");
}

Type guard

boolean hasService(Class<?> c) { return c != null && GcmTaskService.class.isAssignableFrom(c); }

Try / catch

try {
    manager.cancelAllTasks(MyTaskService.class);
} catch (NullPointerException e) {
    Log.e(TAG, "No service configured");
}

Prevention

When it happens

Trigger: Passing a null service class/name into schedule/cancelTask/cancelAllTasks paths, e.g. getClass().getName() on a null reference resolved earlier, or a config field left unset.

Common situations: Service class reference conditioned on build flavor or remote config that resolved to null; refactoring that removed the service but left a variable unset.

Related errors


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