{"record":{"id":"5d691b41f1a554b6","repo":"VictoriaMetrics/VictoriaMetrics","slug":"cannot-create-gcs-client-with-credsfile-q-w","errorCode":null,"errorMessage":"cannot create gcs client with credsFile %q: %w","messagePattern":"cannot create gcs client with credsFile %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/backup/gcsremote/gcs.go","lineNumber":68,"sourceCode":"\tif fs.bkt != nil {\n\t\tlogger.Panicf(\"BUG: fs.Init has been already called\")\n\t}\n\n\tfs.ctx, fs.cancel = context.WithCancel(ctx)\n\n\tfor strings.HasPrefix(fs.Dir, \"/\") {\n\t\tfs.Dir = fs.Dir[1:]\n\t}\n\tif !strings.HasSuffix(fs.Dir, \"/\") {\n\t\tfs.Dir += \"/\"\n\t}\n\n\tvar client *storage.Client\n\tif len(fs.CredsFilePath) > 0 {\n\t\tcreds := option.WithCredentialsFile(fs.CredsFilePath)\n\t\tc, err := storage.NewClient(fs.ctx, creds)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"cannot create gcs client with credsFile %q: %w\", fs.CredsFilePath, err)\n\t\t}\n\t\tclient = c\n\t} else {\n\t\tc, err := storage.NewClient(fs.ctx)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"cannot create default gcs client: %w\", err)\n\t\t}\n\t\tclient = c\n\t}\n\n\tclient.SetRetry(\n\t\tstorage.WithPolicy(storage.RetryAlways),\n\t\tstorage.WithBackoff(gax.Backoff{\n\t\t\tInitial:    time.Second,\n\t\t\tMax:        time.Minute * 3,\n\t\t\tMultiplier: 3,\n\t\t}))\n\tfs.bkt = client.Bucket(fs.Bucket)","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/VictoriaMetrics/VictoriaMetrics/blob/5079fb58f1e8e62113f90c945ad71586c797d770/lib/backup/gcsremote/gcs.go#L50-L86","documentation":"Init creates a Google Cloud Storage client using a credentials JSON file (option.WithCredentialsFile). When storage.NewClient fails with that credentials file, this error wraps the underlying reason - typically an unreadable file or invalid JSON/service-account key. The client is required for all subsequent GCS operations.","triggerScenarios":"Calling fs.Init() with fs.CredsFilePath set where the file does not exist, is unreadable by the process user, contains malformed JSON, is not a valid service-account key, or the storage.NewClient construction itself fails (bad endpoint/option).","commonSituations":"Wrong path in config (relative path resolved from the wrong working directory); k8s secret not mounted or mounted with wrong name; key downloaded from a different project or revoked; JSON truncated during secret rotation.","solutions":["Verify the file exists and is readable: os.Stat the CredsFilePath and check permissions in the runtime environment (container/pod).","Validate the credentials with `gcloud auth activate-service-account --key-file=<path>` or `gcloud projects get-iam-policy` to confirm the key is valid and not revoked.","Use an absolute path for CredsFilePath and confirm the process working directory.","Check the wrapped error text for specifics like 'could not find default credentials' vs JSON parse errors and fix accordingly."],"exampleFix":"// before\nfs.CredsFilePath = \"gcs-key.json\" // relative; fails in service context\n// after\nfs.CredsFilePath = \"/etc/mybackup/secrets/gcs-key.json\"","handlingStrategy":"validation","validationCode":"creds := fs.CredsFilePath\nif creds != \"\" {\n\tif _, err := os.Stat(creds); err != nil {\n\t\treturn fmt.Errorf(\"credentials file missing/unreadable: %w\", err)\n\t}\n\tvar v map[string]any\n\tb, _ := os.ReadFile(creds)\n\tif json.Unmarshal(b, &v) != nil {\n\t\treturn errors.New(\"credentials file is not valid JSON\")\n\t}\n\tif v[\"type\"] != \"service_account\" {\n\t\treturn fmt.Errorf(\"unexpected credential type %v\", v[\"type\"])\n\t}\n}","typeGuard":null,"tryCatchPattern":"if err := fs.Init(); err != nil {\n\tif strings.Contains(err.Error(), \"credsFile\") {\n\t\t// surface config problem: check path, mount, key validity\n\t}\n\treturn fmt.Errorf(\"gcs init failed: %w\", err)\n}","preventionTips":["Mount k8s secrets at stable absolute paths and verify at startup.","Track service-account key age and rotate before revocation.","Validate credential files with gcloud in CI before deploying.","Prefer workload identity/ADC over long-lived key files where possible."],"tags":["gcs","credentials","configuration","google-cloud","go"],"backgroundTag":"invalid-gcp-credentials","analyzedSha":"5079fb58f1e8e62113f90c945ad71586c797d770","analyzedAt":"2026-09-03T18:10:26.153Z","contentChangedAt":"2026-09-03T18:10:26.153Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}