{"record":{"id":"fd07b8aebacc5958","repo":"GoogleContainerTools/skaffold","slug":"deploy-cloud-run-update-service-err","errorCode":"DEPLOY_CLOUD_RUN_UPDATE_SERVICE_ERR","errorMessage":"error deploying Cloud Run Service: %s","messagePattern":"error deploying Cloud Run Service: (.+?)","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/skaffold/deploy/cloudrun/deploy.go","lineNumber":307,"sourceCode":"\t_, err := getCall.Do()\n\n\tif err != nil {\n\t\tgErr, ok := err.(*googleapi.Error)\n\t\tif !ok || gErr.Code != http.StatusNotFound {\n\t\t\treturn nil, sErrors.NewError(fmt.Errorf(\"error checking Cloud Run State: %w\", err), &proto.ActionableErr{\n\t\t\t\tMessage: err.Error(),\n\t\t\t\tErrCode: proto.StatusCode_DEPLOY_CLOUD_RUN_GET_SERVICE_ERR,\n\t\t\t})\n\t\t}\n\t\t// This is a new service, we need to create it\n\t\tcreateCall := crclient.Projects.Locations.Services.Create(parent, service)\n\t\t_, err = createCall.Do()\n\t} else {\n\t\treplaceCall := crclient.Projects.Locations.Services.ReplaceService(sName, service)\n\t\t_, err = replaceCall.Do()\n\t}\n\tif err != nil {\n\t\treturn nil, sErrors.NewError(fmt.Errorf(\"error deploying Cloud Run Service: %s\", err), &proto.ActionableErr{\n\t\t\tMessage: err.Error(),\n\t\t\tErrCode: proto.StatusCode_DEPLOY_CLOUD_RUN_UPDATE_SERVICE_ERR,\n\t\t})\n\t}\n\treturn &resName, nil\n}\n\nfunc (d *Deployer) forceSendValueOfMaxRetries(job *run.Job, manifest []byte) {\n\tmaxRetriesPath := []string{\"spec\", \"template\", \"spec\", \"template\", \"spec\"}\n\tnode := make(map[string]interface{})\n\n\tif err := k8syaml.Unmarshal(manifest, &node); err != nil {\n\t\tlogger.Entry(context.TODO()).Debugf(\"Error unmarshaling job into map, skipping maxRetries ForceSendFields logic: %v\", err)\n\t\treturn\n\t}\n\n\tfor _, field := range maxRetriesPath {\n\t\tvalue := node[field]","sourceCodeStart":289,"sourceCodeEnd":325,"githubUrl":"https://github.com/GoogleContainerTools/skaffold/blob/a1189de023efc32d4b8e11f395acc678aa555011/pkg/skaffold/deploy/cloudrun/deploy.go#L289-L325","documentation":"After determining the service exists or not, `deployService` performs the actual write: `Services.Create` for a new service or `Services.ReplaceService` for an existing one. Any error from either call's `.Do()` is wrapped as 'error deploying Cloud Run Service: %s' with code DEPLOY_CLOUD_RUN_UPDATE_SERVICE_ERR.","triggerScenarios":"`createCall.Do()` or `replaceCall.Do()` returns an error in `deployService` — e.g. image not found/pull denied, invalid service spec rejected by the API (400), revision creation failure, quota exceeded, or conditional update conflicts.","commonSituations":"The image referenced in the manifest isn't pushed to a registry the project can pull from (private repo, wrong tag); `--default-repo` substitution missing so the API can't resolve the image; spec violations like missing `containers` or invalid probes; regional quota limits; IAM preventing the run service agent from pulling the image.","solutions":["Read the API message in the error (it's surfaced via `Message: err.Error()`) — Cloud Run returns detailed reasons for rejected specs","Ensure the image is pushed and accessible: `gcloud run deploy` equivalent requires the container image to exist; check `--default-repo` substitution and the `spec.template.spec.containers[0].image` value","Grant the Cloud Run service agent access to pull from the image registry (Artifact Registry Reader role) for cross-project images","Validate the service spec against the Cloud Run schema; common rejects are bad health-check probes, missing port config, or invalid resource limits","Retry if the failure was transient (e.g. 429/503); check quotas in the GCP console"],"exampleFix":"# before: image not found\nimage: my-app:latest   # never pushed\n# after\nskaffold deploy --default-repo=gcr.io/my-project\n# renders image: gcr.io/my-project/my-app:latest","handlingStrategy":"try-catch","validationCode":"// Ensure the image exists and is pullable before deploying\nfunc imageExists(image string) error {\n\tname := strings.SplitN(image, \":\", 2)[0]\n\treturn exec.Command(\"gcloud\", \"artifacts\", \"docker\", \"images\", \"describe\", name).Run()\n}","typeGuard":null,"tryCatchPattern":"if err := deployer.Deploy(ctx, out, artifacts); err != nil {\n\tvar sErr *sErrors.Error\n\tif errors.As(err, &sErr) && sErr.Status().ErrCode == proto.StatusCode_DEPLOY_CLOUD_RUN_UPDATE_SERVICE_ERR {\n\t\tmsg := sErr.Status().Message\n\t\tswitch {\n\t\tcase strings.Contains(msg, \"IMAGE_PULL\") || strings.Contains(msg, \"image\"):\n\t\t\treturn fmt.Errorf(\"check image exists and is pullable by Cloud Run (%s)\", msg)\n\t\tcase strings.Contains(msg, \"429\") || strings.Contains(msg, \"503\"):\n\t\t\ttime.Sleep(10 * time.Second)\n\t\t\treturn deployer.Deploy(ctx, out, artifacts) // retry transient failures\n\t\t}\n\t}\n\treturn err\n}","preventionTips":["Push images before deploying and use --default-repo so image references resolve to a reachable registry","Grant the Cloud Run service agent Artifact Registry Reader for cross-project images","Validate service spec fields (probes, resources, ports) against the Cloud Run schema","Watch quotas/limits in the region and retry on 429/503 transient errors"],"tags":["cloud-run","deploy","api","container-image"],"backgroundTag":"cloud-run-deploy-failed","analyzedSha":"a1189de023efc32d4b8e11f395acc678aa555011","analyzedAt":"2026-09-05T12:09:27.064Z","contentChangedAt":"2026-09-05T12:09:27.064Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}