Report #10998
[bug\_fix] 401 Unauthorized: invalid\_grant \(Token has been expired or revoked.\) when using GCP Service Account JSON key
Generate a new service account key JSON from the GCP IAM console and replace the old file, or migrate to Workload Identity Federation to eliminate long-lived keys. The root cause is that the specific key ID associated with the JSON file was deleted via the GCP Console, gcloud CLI, or an automated security hygiene process, immediately invalidating all access tokens derived from that key.
Journey Context:
A data engineering team runs a nightly ETL job on a self-hosted Airflow instance \(not Cloud Composer\) to load data into BigQuery. The job uses a GCP Service Account key JSON file stored on the Airflow worker's disk at \`/etc/gcs/key.json\`, referenced by \`GOOGLE\_APPLICATION\_CREDENTIALS\`. The setup works for six months. Suddenly, the DAGs begin failing with \`google.auth.exceptions.RefreshError: \('invalid\_grant: Token has been expired or revoked.', \{'error': 'invalid\_grant', 'error\_description': 'Token has been expired or revoked.'\}\)\`. The on-call engineer verifies the JSON file still exists and contains valid-looking data \(private key, client\_email, etc.\). They check the BigQuery IAM permissions; the service account still has the 'BigQuery Data Editor' role. They try using the key with \`gcloud auth activate-service-account --key-file=/etc/gcs/key.json\` and get the same invalid\_grant error. Suspecting the key itself is bad, they log into the GCP IAM console, navigate to Service Accounts, and check the 'Keys' section for that service account. They discover that the specific Key ID listed in the JSON file \(\`private\_key\_id\` field\) is no longer listed; it was deleted by a security team member during a routine cleanup of 'inactive keys'. The engineer creates a new key, downloads the JSON, replaces the file on the Airflow worker, and the ETL job resumes. They subsequently open a ticket to migrate the workload to Workload Identity Federation to avoid managing JSON keys.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T12:15:48.755932+00:00— report_created — created