GoogleContainerTools/skaffold · error

no project id found in metrics credentials

Error message

no project id found in metrics credentials

What it means

initCloudMonitoringExporterMetrics reads Google Cloud application-default credentials from disk and unmarshals them to extract the project ID. If the credentials JSON has no project_id (or is not valid JSON), it fails with "no project id found in metrics credentials". The Cloud Monitoring metrics exporter cannot be created without a project to write metrics to.

Source

Thrown at pkg/skaffold/instrumentation/export.go:141

		return os.Remove(filename)
	}
	return nil
}

func initCloudMonitoringExporterMetrics() (sdkmetric.Exporter, error) {
	b, err := fs.AssetsFS.ReadFile("assets/secrets_generated/keys.json")
	if err != nil {
		// No keys have been set in this version so do not attempt to write metrics
		if os.IsNotExist(err) {
			return devStdOutExporter()
		}
		return nil, err
	}

	var c creds
	err = json.Unmarshal(b, &c)
	if c.ProjectID == "" || err != nil {
		return nil, fmt.Errorf("no project id found in metrics credentials")
	}

	formatter := func(desc metricdata.Metrics) string {
		return fmt.Sprintf("custom.googleapis.com/skaffold/%s", desc.Name)
	}

	otel.SetErrorHandler(errHandler{})
	return mexporter.New(
		mexporter.WithProjectID(c.ProjectID),
		mexporter.WithMetricDescriptorTypeFormatter(formatter),
		mexporter.WithMonitoringClientOptions(option.WithCredentialsJSON(b)))
}

func devStdOutExporter() (sdkmetric.Exporter, error) {
	// export metrics to std out if local env is set.
	if _, ok := os.LookupEnv("SKAFFOLD_EXPORT_TO_STDOUT"); ok {
		enc := json.NewEncoder(os.Stdout)
		enc.SetIndent("", "  ")

View on GitHub (pinned to a1189de023)

Solutions

  1. Verify the credentials JSON contains "project_id": `cat $GOOGLE_APPLICATION_CREDENTIALS | jq .project_id`.
  2. Re-download or recreate the service account key with `gcloud iam service-accounts keys create`.
  3. Re-run `gcloud auth application-default login` to regenerate valid ADC credentials.

Example fix

// before: credentials missing project_id
{"type": "service_account"}
// after: valid key includes project_id
{"type": "service_account", "project_id": "my-project", ...}
Defensive patterns

Strategy: validation

Validate before calling

b, err := os.ReadFile(os.Getenv("GOOGLE_APPLICATION_CREDENTIALS"))
if err == nil {
    var c struct{ ProjectID string `json:"project_id"` }
    if json.Unmarshal(b, &c) != nil || c.ProjectID == "" {
        log.Println("credentials missing project_id")
    }
}

Type guard

func credsHaveProjectID(b []byte) bool {
    var c struct{ ProjectID string `json:"project_id"` }
    return json.Unmarshal(b, &c) == nil && c.ProjectID != ""
}

Try / catch

if err := runSkaffold(); err != nil {
    if strings.Contains(err.Error(), "no project id found in metrics credentials") {
        // refresh ADC or service-account key
    }
}

Prevention

When it happens

Trigger: Metrics export to Cloud Monitoring is enabled but the credentials file (from GOOGLE_APPLICATION_CREDENTIALS or the ADC well-known path) contains no `project_id` field or is malformed.

Common situations: Using service-account keys created without a project, truncated/partial credentials files, or pointing GOOGLE_APPLICATION_CREDENTIALS at the wrong JSON.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/0b0094d49d4f11e0. Report an issue: GitHub.