{"record":{"id":"af65a5cc84f84df6","repo":"VictoriaMetrics/VictoriaMetrics","slug":"client-id-cannot-be-empty","errorCode":null,"errorMessage":"client_id cannot be empty","messagePattern":"client_id cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/promauth/config.go","lineNumber":156,"sourceCode":"\tHeaders []string `yaml:\"proxy_headers,omitempty\"`\n}\n\n// OAuth2Config represent OAuth2 configuration\ntype OAuth2Config struct {\n\tClientID         string            `yaml:\"client_id\"`\n\tClientSecret     *Secret           `yaml:\"client_secret,omitempty\"`\n\tClientSecretFile string            `yaml:\"client_secret_file,omitempty\"`\n\tScopes           []string          `yaml:\"scopes,omitempty\"`\n\tTokenURL         string            `yaml:\"token_url\"`\n\tEndpointParams   map[string]string `yaml:\"endpoint_params,omitempty\"`\n\tTLSConfig        *TLSConfig        `yaml:\"tls_config,omitempty\"`\n\tProxyURL         string            `yaml:\"proxy_url,omitempty\"`\n\tHeaders          []string          `yaml:\"headers,omitempty\"`\n}\n\nfunc (o *OAuth2Config) validate() error {\n\tif o.ClientID == \"\" {\n\t\treturn fmt.Errorf(\"client_id cannot be empty\")\n\t}\n\tif o.ClientSecret == nil && o.ClientSecretFile == \"\" {\n\t\treturn fmt.Errorf(\"ClientSecret or ClientSecretFile must be set\")\n\t}\n\tif o.ClientSecret != nil && o.ClientSecretFile != \"\" {\n\t\treturn fmt.Errorf(\"ClientSecret and ClientSecretFile cannot be set simultaneously\")\n\t}\n\tif o.TokenURL == \"\" {\n\t\treturn fmt.Errorf(\"token_url cannot be empty\")\n\t}\n\treturn nil\n}\n\ntype oauth2ConfigInternal struct {\n\tmu               sync.Mutex\n\tcfg              *clientcredentials.Config\n\tclientSecretFile string\n","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/VictoriaMetrics/VictoriaMetrics/blob/5079fb58f1e8e62113f90c945ad71586c797d770/lib/promauth/config.go#L138-L174","documentation":"A validation guard in OAuth2Config.validate: the client_id field of the OAuth2 scrape/auth config is empty. The input at fault is the client_id yaml key under oauth2 in the configuration file being loaded.","triggerScenarios":"initFromOAuth2Config -> newOAuth2ConfigInternal -> validate() runs on an OAuth2Config whose ClientID is \"\" — i.e. the config's oauth2.client_id is missing or set to an empty string.","commonSituations":"Forgot to fill client_id in the scrape/remote-write config; environment-variable templating produced an empty value (unset env var); copy-pasted an OAuth2 block but deleted the client_id line.","solutions":["Set client_id in the OAuth2 config block","If using templating/env expansion, verify the variable is set in the process environment before startup","Check the loaded YAML path/indentation so client_id actually lands on the OAuth2 block being validated"],"exampleFix":"// before\noauth2:\n  token_url: https://idp/token\n  client_secret: \"s3cret\"\n// after\noauth2:\n  token_url: https://idp/token\n  client_id: \"my-client\"\n  client_secret: \"s3cret\"","handlingStrategy":"validation","validationCode":"if cfg.OAuth2 != nil && cfg.OAuth2.ClientID == \"\" {\n    return errors.New(\"oauth2.client_id must be set before applying config\")\n}","typeGuard":"func oauth2ClientIDSet(o *promauth.OAuth2Config) bool {\n    return o != nil && o.ClientID != \"\"\n}","tryCatchPattern":"if err := ac.InitFromOAuth2Config(oauthCfg); err != nil {\n    if strings.Contains(err.Error(), \"client_id cannot be empty\") {\n        return fmt.Errorf(\"config error: oauth2 block requires client_id: %w\", err)\n    }\n    return err\n}","preventionTips":["Validate the full config at startup (fail fast) before serving traffic","Check env-var templating produces non-empty values for client_id","Use config schema tests in CI to assert required OAuth2 fields are present","Keep client_id and client_secret defined together in the same config block"],"tags":["oauth2","configuration","validation"],"backgroundTag":"missing-required-config-field","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"}