grpc/grpc-go · error
empty destination project ID
Error message
empty destination project ID
What it means
The config has no project_id and neither the GOOGLE_CLOUD_PROJECT env var nor the GCP default credential exposes a project. Cloud Logging/Trace/Monitoring all need a destination project, so ensureProjectIDInObservabilityConfig refuses to continue. Emitted at config.go:148.
Solutions
- Set "project_id" in the observability config JSON to your GCP project.
- Or export GOOGLE_CLOUD_PROJECT=<your-project> in the process environment.
- Or run `gcloud auth application-default login` so ADC carries a project_id.
- If using a service-account key JSON, ensure it has a "project_id" field and that GOOGLE_APPLICATION_CREDENTIALS points to it.
- On GCE/GKE/Cloud Run the metadata server usually supplies this automatically — verify metadata connectivity if missing.
Example fix
// before
export GRPC_GCP_OBSERVABILITY_CONFIG='{"cloud_logging":{}}'
// after
export GRPC_GCP_OBSERVABILITY_CONFIG='{"project_id":"my-proj","cloud_logging":{}}'
# or
export GOOGLE_CLOUD_PROJECT=my-proj Defensive patterns
Strategy: validation
Validate before calling
func resolveProjectID() (string, error) {
if p := os.Getenv("GOOGLE_CLOUD_PROJECT"); p != "" { return p, nil }
creds, err := google.FindDefaultCredentials(context.Background(), gcplogging.WriteScope)
if err != nil || creds.ProjectID == "" {
return "", errors.New("no project_id: set config.project_id or GOOGLE_CLOUD_PROJECT or run `gcloud auth application-default login`")
}
return creds.ProjectID, nil
}
if _, err := resolveProjectID(); err != nil { return err } Try / catch
if err := observability.Start(ctx); err != nil {
if strings.Contains(err.Error(), "empty destination project ID") {
return fmt.Errorf("set project_id in config or GOOGLE_CLOUD_PROJECT, or provision ADC: %w", err)
}
return err
} Prevention
- Always pin project_id in the config for non-GCP environments.
- Set GOOGLE_CLOUD_PROJECT in your container base image.
- Validate ADC project availability in a startup probe.
When it happens
Trigger: Calling observability.Start where config.project_id is empty AND GOOGLE_CLOUD_PROJECT is unset AND google.FindDefaultCredentials either failed or returned credentials with an empty ProjectID. Common on developer laptops, on-prem, or CI outside GCP metadata.
Common situations: Running locally without `gcloud auth application-default login`; service account JSON key without a project; workload running outside GCE/GKE/Cloud Run metadata; env var renamed (e.g. GCLOUD_PROJECT instead of GOOGLE_CLOUD_PROJECT); ADC scoped to a non-project resource.
Related errors
- cannot have a leading slash
- cannot have exclude and a '*' wildcard
- error in clientRPCEvent method
- error in serverRPCEvent method
- error parsing observability config: invalid cloud trace…
AI-assisted analysis of grpc/grpc-go@0c51461d27 (2026-08-11).
Data as JSON: /api/errors/c9008dcde8bcd8ba.
Report an issue: GitHub.
Appendix: source
Thrown at gcp/observability/config.go:148
}
content, err := os.ReadFile(f)
if err != nil {
return nil, fmt.Errorf("error reading observability configuration file %q: %v", f, err)
}
return unmarshalAndVerifyConfig(content)
} else if envconfig.ObservabilityConfig != "" {
return unmarshalAndVerifyConfig([]byte(envconfig.ObservabilityConfig))
}
// If the ENV var doesn't exist, do nothing
return nil, nil
}
func ensureProjectIDInObservabilityConfig(ctx context.Context, config *config) error {
if config.ProjectID == "" {
// Try to fetch the GCP project id
projectID := fetchDefaultProjectID(ctx)
if projectID == "" {
return fmt.Errorf("empty destination project ID")
}
config.ProjectID = projectID
}
return nil
}
type clientRPCEvents struct {
// Methods is a list of strings which can select a group of methods. By
// default, the list is empty, matching no methods.
//
// The value of the method is in the form of <service>/<method>.
//
// "*" is accepted as a wildcard for:
// 1. The method name. If the value is <service>/*, it matches all
// methods in the specified service.
// 2. The whole value of the field which matches any <service>/<method>.
// It’s not supported when Exclude is true.
// 3. The * wildcard cannot be used on the service name independently,View on GitHub (pinned to 0c51461d27)