From 60aef0510f180dc82d217bcd55d4f0aa5f4c19e9 Mon Sep 17 00:00:00 2001 From: andriibeee <154226341+andriibeee@users.noreply.github.com> Date: Thu, 26 Mar 2026 11:18:37 +0200 Subject: [PATCH] lib/promauth: make username optional in basic_auth section RFC-7617 allows empty password/username. Moreover, from RFC standpoint both empty values are valid as well. It should be just encoded as `:`. So this commit relaxes non-empty username restriction. Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6956 --- docs/victoriametrics/changelog/CHANGELOG.md | 1 + docs/victoriametrics/sd_configs.md | 4 ++-- lib/promauth/config.go | 14 +++++++++-- lib/promauth/config_test.go | 5 ++-- lib/promscrape/config_test.go | 26 +++++++++++++++++++-- 5 files changed, 41 insertions(+), 9 deletions(-) diff --git a/docs/victoriametrics/changelog/CHANGELOG.md b/docs/victoriametrics/changelog/CHANGELOG.md index 924c7c84da..923639b028 100644 --- a/docs/victoriametrics/changelog/CHANGELOG.md +++ b/docs/victoriametrics/changelog/CHANGELOG.md @@ -31,6 +31,7 @@ See also [LTS releases](https://docs.victoriametrics.com/victoriametrics/lts-rel * FEATURE: [vmalert](https://docs.victoriametrics.com/victoriametrics/vmalert/): add `search` parameter and pagination support in `/api/v1/rules` API. See [#10046](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/10046). * FEATURE: [vmui](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/#vmui): add default pagination to improve the Alerting Rules page experience when vmalert loads thousands of rules. See [#10046](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/10046). * FEATURE: all VictoriaMetrics components: log a warning when an IPv6 listen address (e.g. `[::]:6969`) is specified but `-enableTCP6` is not set. Previously, the server silently listened on IPv4 only. See [#6858](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6858). Thanks to @andriibeee for the contribution. +* FEATURE: [vmagent](https://docs.victoriametrics.com/victoriametrics/vmagent/): allow specifying `basic_auth` in scrape configs without `username`. Previously this resulted in a config error. Now a warning is logged instead. See [#6956](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/6956). Thanks to @andriibeee for the contribution. * BUGFIX: `vmselect` in [VictoriaMetrics cluster](https://docs.victoriametrics.com/victoriametrics/cluster-victoriametrics/): retry RPC by dialing a new connection instead of reusing a pooled one when the previous attempt fails with `io.EOF`, `broken pipe` or `reset by peer`. This reduces query failures caused by stale connections to restarted vmstorage nodes. See [#10314](https://github.com/VictoriaMetrics/VictoriaMetrics/issues/10314) * BUGFIX: [vmui](https://docs.victoriametrics.com/victoriametrics/single-server-victoriametrics/#vmui): fix autocomplete dropdown not closing on the Raw Query page. See [#10665](https://github.com/VictoriaMetrics/VictoriaMetrics/pull/10665) diff --git a/docs/victoriametrics/sd_configs.md b/docs/victoriametrics/sd_configs.md index 9ac3553e54..4f8d071275 100644 --- a/docs/victoriametrics/sd_configs.md +++ b/docs/victoriametrics/sd_configs.md @@ -2080,8 +2080,8 @@ and in the majority of [supported service discovery configs](#supported-service- # basic_auth is an optional HTTP basic authentication configuration. # # basic_auth: - # username: "..." - # username_file: "..." # is mutually-exclusive with username + # username: "..." # optional + # username_file: "..." # optional, is mutually-exclusive with username # password: "..." # password_file: "..." # is mutually-exclusive with password diff --git a/lib/promauth/config.go b/lib/promauth/config.go index 6935d09210..9f439df334 100644 --- a/lib/promauth/config.go +++ b/lib/promauth/config.go @@ -823,10 +823,20 @@ func (actx *authContext) initFromBasicAuthConfig(baseDir string, ba *BasicAuthCo password = ba.Password.S } passwordFile := ba.PasswordFile - if username == "" && usernameFile == "" { - return fmt.Errorf("missing `username` and `username_file` in `basic_auth` section; please specify one; " + + if username == "" && usernameFile == "" && password == "" && passwordFile == "" { + return fmt.Errorf("missing `username`, `username_file`, `password` and `password_file` in `basic_auth` section; please specify at least one; " + "see https://docs.victoriametrics.com/victoriametrics/sd_configs/#http-api-client-options") } + if username == "" && usernameFile == "" { + logger.Warnf("missing `username` and `username_file` in `basic_auth` section; " + + "see https://docs.victoriametrics.com/victoriametrics/sd_configs/#http-api-client-options") + } + if strings.TrimSpace(username) == "" && username != "" { + logger.Warnf("`username` in `basic_auth` section is blank; it is possible to omit the `username` value if it is not needed") + } + if usernameFile == "/dev/null" { + logger.Warnf("`username_file` in `basic_auth` section points to /dev/null; it is possible to omit the `username_file` value if it is not needed") + } if username != "" && usernameFile != "" { return fmt.Errorf("both `username` and `username_file` are set in `basic_auth` section; please specify only one; " + "see https://docs.victoriametrics.com/victoriametrics/sd_configs/#http-api-client-options") diff --git a/lib/promauth/config_test.go b/lib/promauth/config_test.go index f953e72946..9533d666c7 100644 --- a/lib/promauth/config_test.go +++ b/lib/promauth/config_test.go @@ -58,10 +58,9 @@ basic_auth: password: pass `) - // basic_auth: missing username + // basic_auth: empty basic_auth section f(` -basic_auth: - password: pass +basic_auth: {} `) // basic_auth: both username and username_file are set diff --git a/lib/promscrape/config_test.go b/lib/promscrape/config_test.go index a7e7069330..3dd1f86c38 100644 --- a/lib/promscrape/config_test.go +++ b/lib/promscrape/config_test.go @@ -670,12 +670,12 @@ scrape_configs: - targets: ["foo"] `, []*ScrapeWork{}) - // Scrape config with missing username in `basic_auth` must be skipped + // Scrape configs that omit the password in basic_auth must be skipped. f(` scrape_configs: - job_name: x basic_auth: - password: sss + password: "" static_configs: - targets: ["a"] `, []*ScrapeWork{}) @@ -780,6 +780,28 @@ scrape_configs: }, }) + // Scrape configs that include a password but omit the username should still be parsed correctly + f(` +scrape_configs: +- job_name: x + basic_auth: + password: sss + static_configs: + - targets: ["a"] +`, []*ScrapeWork{ + { + ScrapeURL: "http://a/metrics", + ScrapeInterval: defaultScrapeInterval, + ScrapeTimeout: defaultScrapeTimeout, + MaxScrapeSize: maxScrapeSize.N, + Labels: promutil.NewLabelsFromMap(map[string]string{ + "instance": "a:80", + "job": "x", + }), + jobNameOriginal: "x", + }, + }) + f(` scrape_configs: - job_name: foo