{"record":{"id":"ab476cdd42ee0a96","repo":"VictoriaMetrics/VictoriaMetrics","slug":"cannot-get-api-config-w-ab476c","errorCode":null,"errorMessage":"cannot get API config: %w","messagePattern":"cannot get API config: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/promscrape/discovery/digitalocean/digitalocean.go","lineNumber":37,"sourceCode":"\t\"This works only if digitalocean_sd_configs is configured in '-promscrape.config' file. \"+\n\t\"See https://docs.victoriametrics.com/victoriametrics/sd_configs/#digitalocean_sd_configs for details\")\n\n// SDConfig represents service discovery config for digital ocean.\n//\n// See https://prometheus.io/docs/prometheus/latest/configuration/configuration/#digitalocean_sd_config\ntype SDConfig struct {\n\tServer            string                     `yaml:\"server,omitempty\"`\n\tHTTPClientConfig  promauth.HTTPClientConfig  `yaml:\",inline\"`\n\tProxyURL          *proxy.URL                 `yaml:\"proxy_url,omitempty\"`\n\tProxyClientConfig promauth.ProxyClientConfig `yaml:\",inline\"`\n\tPort              int                        `yaml:\"port,omitempty\"`\n}\n\n// GetLabels returns Digital Ocean droplet labels according to sdc.\nfunc (sdc *SDConfig) GetLabels(baseDir string) ([]*promutil.Labels, error) {\n\tcfg, err := getAPIConfig(sdc, baseDir)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"cannot get API config: %w\", err)\n\t}\n\tdroplets, err := getDroplets(cfg.client.GetAPIResponse)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn addDropletLabels(droplets, cfg.port), nil\n}\n\n// https://developers.digitalocean.com/documentation/v2/#retrieve-an-existing-droplet-by-id\ntype droplet struct {\n\tID     int    `json:\"id\"`\n\tName   string `json:\"name\"`\n\tStatus string `json:\"status\"`\n\n\tFeatures []string      `json:\"features\"`\n\tImage    dropletImage  `json:\"image\"`\n\tSizeSlug string        `json:\"size_slug\"`\n\tNetworks networks      `json:\"networks\"`","sourceCodeStart":19,"sourceCodeEnd":55,"githubUrl":"https://github.com/VictoriaMetrics/VictoriaMetrics/blob/5079fb58f1e8e62113f90c945ad71586c797d770/lib/promscrape/discovery/digitalocean/digitalocean.go#L19-L55","documentation":"GetLabels is the entry point for DigitalOcean service discovery. This error wraps any failure returned while obtaining (or constructing and caching) the apiConfig — i.e. any of the auth-parse, proxy-auth-parse, or client-creation errors above — so it fires at config-usage time, not request time.","triggerScenarios":"digitalocean_sd_config with broken http_client_config, proxy_client_config, or api_server such that newAPIConfig fails; the config map re-creates the client after a config reload and hits the same failure.","commonSituations":"First scrape after adding a digitalocean_sd_config with a typo; credentials file deleted after initial config load; certificate rotation breaking TLS config; indentation errors after editing prometheus.yml.","solutions":["Look at the wrapped cause after 'cannot get API config:' — it will name the real failing step","Validate the entire digitalocean_sd_config block (auth, proxy, server fields)","Ensure all referenced files (tokens, certs, CA) exist and are readable by vmagent","Reload vmagent config only after running config validation","Temporarily use defaults (no http_client_config) to isolate which subsection is broken"],"exampleFix":"# before\n- digitalocean_sd_configs:\n    - port: 80\n      http_client_config:\n        authorization:\n          credentials_file: /etc/do/missing.txt\n\n# after\n- digitalocean_sd_configs:\n    - port: 80\n      http_client_config:\n        authorization:\n          credentials: <base64 of token or use credentials_file with an existing file>","handlingStrategy":"validation","validationCode":"# Validate the whole digitalocean_sd_config before reload:\n# - http_client_config auth files exist and readable\n# - proxy files exist\n# - server is a valid URL\nfor f in /etc/do/token.txt /etc/do/ca.pem; do test -r \"$f\" || { echo \"missing $f\"; exit 1; }; done\n# then run vmagent config validation","typeGuard":null,"tryCatchPattern":"labels, err := sdc.GetLabels(baseDir)\nif err != nil {\n    var cfgErr = strings.Contains(err.Error(), \"cannot get API config\")\n    if cfgErr {\n        // surface the wrapped cause (auth/proxy/client) to config tooling; fix and re-validate\n    }\n    return err\n}","preventionTips":["Run config validation on every config change before reload","Never delete/rotate credential files without updating the config","Keep sd_config subsections correctly nested in YAML","Stage config reloads with a canary vmagent instance"],"tags":["digitalocean","config","service-discovery"],"backgroundTag":"auth-config-parse-failed","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"}