Google Container Registry (gcr.io) "denied: ... does not have storage.objects" in CI
Container Registry (gcr.io) stores images in a Cloud Storage bucket, so push permission is a Storage permission, not an Artifact Registry one. A push denied for "storage.objects.create" means the service account lacks write access to the gcr.io bucket. Grant a Storage role on that bucket (or migrate to Artifact Registry).
What this error means
docker push to gcr.io/PROJECT/app fails with "denied: ... does not have storage.objects.create access to the Google Cloud Storage object" or a 403 referencing the artifacts.PROJECT.appspot.com bucket.
denied: Permission denied. The service account does not have
storage.objects.create access to the bucket artifacts.my-proj.appspot.comCommon causes
No Storage write role on the GCR bucket
gcr.io is bucket-backed. Without storage.objects.create (e.g. roles/storage.admin) on the GCR bucket, the push is denied.
Wrong identity or project in the tag
The push authenticates as a service account with no rights to that project bucket, or the project in the gcr.io tag is wrong.
How to fix it
Grant a Storage role on the GCR bucket
- Identify the CI service account.
- Grant roles/storage.admin on the project (or the gcr.io bucket).
- Re-authenticate docker with gcloud and push again.
gsutil iam ch \
serviceAccount:ci@my-proj.iam.gserviceaccount.com:roles/storage.admin \
gs://artifacts.my-proj.appspot.comMigrate to Artifact Registry
gcr.io now routes through Artifact Registry. Pushing to *-docker.pkg.dev uses Artifact Registry IAM (Writer role) and avoids bucket-level Storage grants.
gcloud auth configure-docker us-docker.pkg.devHow to prevent it
- Grant Storage write on the GCR bucket for legacy gcr.io pushes.
- Prefer Artifact Registry with roles/artifactregistry.writer.
- Verify the project in the gcr.io image tag.