You’ve hit the classic post-migration configuration gap. All three focus areas need attention:
Pub/Sub Topic Migration Checklist:
When migrating Pub/Sub topics, you need to update multiple configurations:
- IoT Core device registry must point to the new state topic:
gcloud iot registries update REGISTRY_NAME \
--region=REGION \
--state-pubsub-topic=projects/PROJECT/topics/NEW_TOPIC
This is the most commonly missed step. Even though events are appearing in your subscription, they might be coming from a different source than expected. Verify your registry configuration with gcloud iot registries describe.
Device State Event Subscriptions:
Your new subscription needs these exact settings to match the old behavior:
- Delivery type: must match your monitoring service (push vs pull)
- Message retention: set to at least 7 days for reliability
- Ack deadline: 60 seconds minimum for state processing
- Dead letter topic: configure to catch processing failures
- Message ordering: enable if you need sequential state updates
Critically, check if your old subscription had a message filter. Device state events include connects, disconnects, errors, and config updates. If your monitoring service only processes connect/disconnect events, add this filter:
attributes.subFolder="state" AND (attributes.deviceId!="")
IAM Permissions Verification:
You need three separate IAM bindings:
- IoT Core service account → Publisher on state topic:
gcloud pubsub topics add-iam-policy-binding NEW_TOPIC \
--member=serviceAccount:cloud-iot@system.gserviceaccount.com \
--role=roles/pubsub.publisher
- Monitoring service account → Subscriber on subscription:
gcloud pubsub subscriptions add-iam-policy-binding SUBSCRIPTION \
--member=serviceAccount:monitoring-service@PROJECT.iam.gserviceaccount.com \
--role=roles/pubsub.subscriber
- Monitoring service account → Viewer on subscription (for monitoring):
gcloud pubsub subscriptions add-iam-policy-binding SUBSCRIPTION \
--member=serviceAccount:monitoring-service@PROJECT.iam.gserviceaccount.com \
--role=roles/pubsub.viewer
The third binding is often forgotten but necessary for the monitoring service to check subscription metrics.
Debugging steps:
- Enable Cloud Logging for your subscription to see delivery attempts
- Check if messages are being delivered but not acked (indicates processing failure)
- Verify your monitoring service logs for permission errors
- Test with a simple pull subscription to confirm messages are reachable
One gotcha we discovered: if you’re using push subscriptions with authentication, the endpoint URL must be updated in the subscription configuration. The old subscription might have had a different push endpoint than what your monitoring service is now listening on.
After fixing all three areas, you should see state updates within 30 seconds of device events. Set up monitoring on subscription/num_undelivered_messages to alert if state events aren’t being processed.