GoogleContainerTools/skaffold · error
StatusCode_DEPLOY_CLOUD_RUN_DELETE_SERVICE_ERR
StatusCode_DEPLOY_CLOUD_RUN_DELETE_SERVICE_ERR
Error message
unable to delete Cloud Run Service
What it means
Thrown by deleteRunService when the Cloud Run API Delete call (crclient.Projects.Locations.Services.Delete(sName).Do()) returns an error. The project/region/service resource name were resolved fine, but the API refused or failed the deletion. The underlying API error text is surfaced in the actionable error Message.
Source
Thrown at pkg/skaffold/deploy/cloudrun/deploy.go:555
projectID = service.Metadata.Namespace
default:
// no project specified, we don't know what to delete.
return sErrors.NewError(fmt.Errorf("unable to determine Google Cloud Project"), &proto.ActionableErr{
Message: "No Google Cloud Project found in Cloud Run manifest or Skaffold Manifest.",
ErrCode: proto.StatusCode_DEPLOY_READ_MANIFEST_ERR,
})
}
parent := fmt.Sprintf("projects/%s/locations/%s", projectID, d.Region)
sName := fmt.Sprintf("%s/services/%s", parent, service.Metadata.Name)
if dryRun {
output.Yellow.Fprintln(out, sName)
return nil
}
delCall := crclient.Projects.Locations.Services.Delete(sName)
_, err := delCall.Do()
if err != nil {
return sErrors.NewError(fmt.Errorf("unable to delete Cloud Run Service"), &proto.ActionableErr{
Message: err.Error(),
ErrCode: proto.StatusCode_DEPLOY_CLOUD_RUN_DELETE_SERVICE_ERR,
})
}
return nil
}
func (d *Deployer) deleteRunJob(crclient *run.APIService, out io.Writer, dryRun bool, manifest []byte) error {
job := &run.Job{}
if err := k8syaml.Unmarshal(manifest, job); err != nil {
return sErrors.NewError(fmt.Errorf("unable to unmarshal Cloud Run Job config: %w", err), &proto.ActionableErr{
Message: err.Error(),
ErrCode: proto.StatusCode_DEPLOY_READ_MANIFEST_ERR,
})
}
var projectID string
switch {
case d.Project != "":View on GitHub (pinned to a1189de023)
Solutions
- Read the embedded err.Error() in the actionable error: if 404, the service is already gone and cleanup can be re-run/ignored
- Verify gcloud auth and IAM: the identity needs roles/run.admin (run.services.delete)
- Confirm deploy.cloudrun.region matches the region the service was deployed to
- Retry on transient (5xx/network) failures after checking service state
Example fix
// before: deleting in wrong region
deploy:
cloudrun:
region: us-central1
// after: match the region used at deploy time
deploy:
cloudrun:
region: us-east1 Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check before delete
call := crclient.Projects.Locations.Services.Get(sName)
if _, err := call.Do(); err != nil {
if gErr, ok := err.(*googleapi.Error); ok && gErr.Code == 404 {
return nil // already deleted, skip
}
return err
} Try / catch
if _, err := delCall.Do(); err != nil {
if gErr, ok := err.(*googleapi.Error); ok {
switch gErr.Code {
case 404:
return nil // idempotent delete
case 403:
return fmt.Errorf("IAM: needs run.services.delete: %w", err)
case 429, 500, 503:
return retryWithBackoff(delCall)
}
}
return err
} Prevention
- Make cleanup idempotent: treat 404 as success
- Grant the CI identity roles/run.admin (run.services.delete permission)
- Keep region configured identically for deploy and cleanup
- Check the service's status before deleting (deletion already in progress returns an error)
When it happens
Trigger: cleanupRun -> deleteRunService calls Projects.Locations.Services.Delete on projects/<proj>/locations/<region>/services/<name> and the API returns a non-2xx response or transport error.
Common situations: Service already deleted (404) or never existed; wrong region configured; missing run.services.delete IAM permission or expired credentials; API not enabled; transient network failures; service has a delete-blocking state (e.g. deletion already in progress).
Related errors
- StatusCode_DEPLOY_CLOUD_RUN_DELETE_WORKER_POOL_ERR
- INIT_CLOUD_RUN_LOCATION_ERROR
- DEPLOY_CLOUD_RUN_GET_SERVICE_ERR
- DEPLOY_CLOUD_RUN_UPDATE_SERVICE_ERR
- StatusCode_DEPLOY_GET_CLOUD_RUN_CLIENT_ERR
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/38de4b8cc50fd306.
Report an issue: GitHub.