microg/GmsCore · error · IOException

ERROR_MAIN_THREAD

ERROR_MAIN_THREAD

Error message

ERROR_MAIN_THREAD

What it means

GCM error surfaced as IOException('ERROR_MAIN_THREAD') from GoogleCloudMessaging.register: the registration was attempted on the main thread, which GCM forbids for network operations. The faulty input is the calling thread, not the sender IDs.

Source

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

     * <p/>
     * Repeated calls to this method will return the original registration ID.
     * <p/>
     * If you want to modify the list of senders, you must call <code>unregister()</code> first.
     * <p/>
     * Most applications use a single sender ID. You may use multiple senders if different
     * servers may send messages to the app or for testing.</p>
     *
     * @param senderIds list of project numbers or Google accounts identifying who is allowed to
     *                  send messages to this application.
     * @return registration id
     * @throws IOException
     * @deprecated Instead, for GCM registration, use
     * {@link com.google.android.gms.iid.InstanceID#getToken(java.lang.String, java.lang.String)}.
     * Set authorizedEntity to a sender ID and scope to {@link com.google.android.gms.gcm.GoogleCloudMessaging#INSTANCE_ID_SCOPE}.
     */
    @Deprecated
    public String register(String... senderIds) throws IOException {
        if (Looper.getMainLooper() == Looper.myLooper()) throw new IOException(ERROR_MAIN_THREAD);

        if (senderIds == null || senderIds.length == 0) throw new IllegalArgumentException("No sender ids");
        StringBuilder sb = new StringBuilder(senderIds[0]);
        for (int i = 1; i < senderIds.length; i++) {
            sb.append(',').append(senderIds[i]);
        }
        String sender = sb.toString();

        if (isLegacyFallback()) {
            Bundle extras = new Bundle();
            extras.putString(EXTRA_SENDER_LEGACY, sender);
            return InstanceID.getInstance(context).getToken(sb.toString(), INSTANCE_ID_SCOPE, extras);
        } else {
            Bundle extras = new Bundle();
            extras.putString(EXTRA_SENDER, sender);
            return rpc.handleRegisterMessageResult(rpc.sendRegisterMessageBlocking(extras));
        }
    }

View on GitHub (pinned to 157c9d86ac)

Solutions

  1. Move register()/unregister() off the UI thread (executor, AsyncTask, or Dispatchers.IO)
  2. Catch the IOException and re-attempt from a worker thread
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at play-services-gcm/src/main/java/com/google/android/gms/gcm/GoogleCloudMessaging.java:194 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/46fbf28a3946e256. Report an issue: GitHub.