kubernetes/kops · error
--project cannot be empty; specify a project or omit the fla
Error message
--project cannot be empty; specify a project or omit the flag to use the gcloud default project
What it means
checkProjectFlag rejects an explicitly-set but empty --project flag for the GCE provider. An empty value usually comes from --project=$PROJECT where the environment variable is unset, and silently falling back to the gcloud default project may target the wrong project. It is a pure input-validation error raised before any cloud calls.
Source
Thrown at cmd/kops/create_cluster.go:935
fmt.Fprintf(&sb, "Finally configure your cluster with: kops update cluster --name %s --yes --admin\n", cluster.Name)
fmt.Fprintf(&sb, "\n")
_, err := out.Write(sb.Bytes())
if err != nil {
return fmt.Errorf("error writing to output: %v", err)
}
}
}
return nil
}
// checkProjectFlag rejects an explicitly empty --project flag. An empty value usually comes from
// an unset environment variable (e.g. --project=$PROJECT); silently accepting it would fall back
// to the gcloud default project, which may not be the intended one.
func checkProjectFlag(flagSet bool, project string) error {
if flagSet && project == "" {
return fmt.Errorf("--project cannot be empty; specify a project or omit the flag to use the gcloud default project")
}
return nil
}
// parseCloudLabels takes a CSV list of key=value records and parses them into a map. Nested '='s are supported via
// quoted strings (eg `foo="bar=baz"` parses to map[string]string{"foo":"bar=baz"}. Nested commas are not supported.
func parseCloudLabels(s string) (map[string]string, error) {
// Replace commas with newlines to allow a single pass with csv.Reader.
// We can't use csv.Reader for the initial split because it would see each key=value record as a single field
// and significantly complicates using quoted fields as keys or values.
records := strings.ReplaceAll(s, ",", "\n")
// Let the CSV library do the heavy-lifting in handling nested ='s
r := csv.NewReader(strings.NewReader(records))
r.Comma = '='
r.FieldsPerRecord = 2
r.LazyQuotes = false
r.TrimLeadingSpace = trueView on GitHub (pinned to 4c8573c808)
Solutions
- Export the variable: export PROJECT=my-gcp-project before running kops.
- Hardcode the project ID: --project my-gcp-project.
- Or omit --project entirely to accept the gcloud default (verify with gcloud config get-value project).
- Check the CI pipeline passes the project env var into the job.
Example fix
// before kops create cluster --cloud gce --project=$PROJECT ... # PROJECT unset // after export PROJECT=my-gcp-project kops create cluster --cloud gce --project=$PROJECT ...
Defensive patterns
Strategy: validation
Validate before calling
func guardProjectFlag(flagSet bool, project string) error {
if flagSet && strings.TrimSpace(project) == "" {
return fmt.Errorf("--project was set but resolves to empty; check $PROJECT")
}
return nil
}
// call before invoking kops:
// if err := guardProjectFlag(projectFlagPresent, os.Getenv("PROJECT")); err != nil { ... } Type guard
func hasProjectFlag(args []string) (bool, string) {
for i, a := range args {
if a == "--project" && i+1 < len(args) {
return true, args[i+1]
}
if strings.HasPrefix(a, "--project=") {
return true, strings.TrimPrefix(a, "--project=")
}
}
return false, ""
} Prevention
- Export the GCP project env var in shell profiles and CI jobs.
- Default the flag in scripts: PROJECT="${PROJECT:-my-default-project}".
- Verify with gcloud config get-value project before relying on the gcloud default.
- Use set -u in bash to fail fast on unset variables.
When it happens
Trigger: `kops create cluster --cloud gce --project=$PROJECT ...` where $PROJECT is unset/empty (flagSet=true, project=""), hitting the guard at the top of checkProjectFlag.
Common situations: CI jobs missing the GCP project env export; copy-pasting commands referencing another machine's env; shell quoting swallowing the variable (single quotes around $PROJECT).
Related errors
- unsupported output type %q
- cannot specify --key with "all"
- cannot specify --primary with "all"
- --name is required
- unsupported output format: %q
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/cdc6ff841ecda5e5.
Report an issue: GitHub.