{"record":{"id":"68e733582ea184ef","repo":"VictoriaMetrics/VictoriaMetrics","slug":"cannot-set-both-token-and-bearer-token-configs","errorCode":null,"errorMessage":"cannot set both token and bearer_token configs","messagePattern":"cannot set both token and bearer_token configs","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/promscrape/discovery/consul/api.go","lineNumber":48,"sourceCode":"var configMap = discoveryutil.NewConfigMap()\n\nfunc getAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) {\n\tv, err := configMap.Get(sdc, func() (any, error) { return newAPIConfig(sdc, baseDir) })\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn v.(*apiConfig), nil\n}\n\nfunc newAPIConfig(sdc *SDConfig, baseDir string) (*apiConfig, error) {\n\thcc := sdc.HTTPClientConfig\n\ttoken, err := GetToken(sdc.Token)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tif token != \"\" {\n\t\tif hcc.BearerToken != nil {\n\t\t\treturn nil, fmt.Errorf(\"cannot set both token and bearer_token configs\")\n\t\t}\n\t\thcc.BearerToken = promauth.NewSecret(token)\n\t}\n\tif len(sdc.Username) > 0 {\n\t\tif hcc.BasicAuth != nil {\n\t\t\treturn nil, fmt.Errorf(\"cannot set both username and basic_auth configs\")\n\t\t}\n\t\thcc.BasicAuth = &promauth.BasicAuthConfig{\n\t\t\tUsername: sdc.Username,\n\t\t\tPassword: sdc.Password,\n\t\t}\n\t}\n\tac, err := hcc.NewConfig(baseDir)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot parse auth config: %w\", err)\n\t}\n\tapiServer := sdc.Server\n\tif apiServer == \"\" {","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/VictoriaMetrics/VictoriaMetrics/blob/5079fb58f1e8e62113f90c945ad71586c797d770/lib/promscrape/discovery/consul/api.go#L30-L66","documentation":"The consul_sd_config in VictoriaMetrics promscrape supports two mutually exclusive ways to authenticate requests to the Consul API: the `token` field (or CONSUL_HTTP_TOKEN / CONSUL_HTTP_TOKEN_FILE env vars) and the promauth `bearer_token` field inside `http_client_config`. When a token resolves to a non-empty value and `bearer_token` is also set, newAPIConfig refuses to build the API config because only one Authorization mechanism can be used, and returns this error at consul/api.go:48.","triggerScenarios":"Calling getAPIConfig/newAPIConfig with an SDConfig where sdc.Token resolves to a non-empty string (via token field, CONSUL_HTTP_TOKEN, or CONSUL_HTTP_TOKEN_FILE) AND sdc.HTTPClientConfig.BearerToken is non-nil (bearer_token set in the scrape config).","commonSituations":"Operators migrating from token-only configs to a shared http_client_config block and leaving both keys present; CONSUL_HTTP_TOKEN or CONSUL_HTTP_TOKEN_FILE exported in the environment while the YAML also sets bearer_token; copy-pasting prometheus scrape configs where bearer_token was used and adding a consul token later.","solutions":["Remove the bearer_token field from the consul_sd_config's http_client_config and keep only `token`.","Unset the CONSUL_HTTP_TOKEN / CONSUL_HTTP_TOKEN_FILE environment variables on theVictoriaMetrics process if bearer_token should take precedence instead.","Keep only one mechanism: delete `token` from the config if bearer_token is the intended auth method."],"exampleFix":"// before\nconsul_sd_config:\n  server: \"consul:8500\"\n  token: \"my-consul-token\"\n  http_client_config:\n    bearer_token: \"other-token\"\n// after\nconsul_sd_config:\n  server: \"consul:8500\"\n  token: \"my-consul-token\"\n","handlingStrategy":"validation","validationCode":"func validateConsulTokenConflict(sdc *consul.SDConfig) error {\n    token, err := consul.GetToken(sdc.Token)\n    if err != nil {\n        return err\n    }\n    if token != \"\" && sdc.HTTPClientConfig.BearerToken != nil {\n        return fmt.Errorf(\"consul_sd_config: set only one of `token` and `bearer_token`\")\n    }\n    return nil\n}","typeGuard":"func hasBothTokenAndBearer(sdc *consul.SDConfig) bool {\n    token, _ := consul.GetToken(sdc.Token)\n    return token != \"\" && sdc.HTTPClientConfig.BearerToken != nil\n}","tryCatchPattern":"if _, err := consul.GetAPIConfig(sdc, baseDir); err != nil {\n    if strings.Contains(err.Error(), \"cannot set both token and bearer_token\") {\n        // fix config: drop one auth mechanism, then retry\n        return fmt.Errorf(\"invalid consul_sd_config: %w\", err)\n    }\n    return err\n}","preventionTips":["Pick one auth mechanism per consul_sd_config and document it in your config standards.","Before adding bearer_token to http_client_config, check whether `token` or CONSUL_HTTP_TOKEN(_FILE) is already in play.","Run -promscrape.config dry-run validation on every config change in CI."],"tags":["config","authentication","consul","promscrape","conflicting-options"],"backgroundTag":"conflicting-auth-config","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"}