grafana/k6 · error
sigV4 config `Region`, `AwsAccessKeyID`, `AwsSecretAccessKey
Error message
sigV4 config `Region`, `AwsAccessKeyID`, `AwsSecretAccessKey` must all be set
What it means
Returned by sigv4.Config.validate() (via NewRoundTripper) when Region, AwsAccessKeyID, or AwsSecretAccessKey is empty after trimming whitespace. This is the second, lower-level guard behind the output-level partial-config check (config.go:141) and also fires for programmatic users of the exported sigv4 package, including a nil config.
Source
Thrown at internal/output/prometheusrw/sigv4/tripper.go:31
next http.RoundTripper
}
// Config holds aws access configurations
type Config struct {
Region string
AwsAccessKeyID string
AwsSecretAccessKey string
}
func (c *Config) validate() error {
if c == nil {
return errors.New("config should not be nil")
}
hasRegion := len(strings.TrimSpace(c.Region)) != 0
hasAccessID := len(strings.TrimSpace(c.AwsAccessKeyID)) != 0
hasSecretAccessKey := len(strings.TrimSpace(c.AwsSecretAccessKey)) != 0
if !hasRegion || !hasAccessID || !hasSecretAccessKey {
return errors.New("sigV4 config `Region`, `AwsAccessKeyID`, `AwsSecretAccessKey` must all be set")
}
return nil
}
// NewRoundTripper creates a new sigv4 round tripper
func NewRoundTripper(config *Config, next http.RoundTripper) (*Tripper, error) {
if err := config.validate(); err != nil {
return nil, err
}
if next == nil {
next = http.DefaultTransport
}
tripper := &Tripper{
config: config,
next: next,
signer: newDefaultSigner(config),View on GitHub (pinned to 93accf6570)
Solutions
- Populate all three fields with non-blank strings before calling NewRoundTripper
- Pre-trim and check each value at the point where you build the Config; fail with a clear message naming the missing field
- If you have no AWS credentials, do not wrap the transport with sigv4 at all
Example fix
// before
rt, err := sigv4.NewRoundTripper(&sigv4.Config{Region: "us-east-1"}, http.DefaultTransport)
// err: sigV4 config `Region`, `AwsAccessKeyID`, `AwsSecretAccessKey` must all be set
// after
cfg := &sigv4.Config{
Region: "us-east-1",
AwsAccessKeyID: os.Getenv("AWS_ACCESS_KEY_ID"),
AwsSecretAccessKey: os.Getenv("AWS_SECRET_ACCESS_KEY"),
}
if strings.TrimSpace(cfg.AwsAccessKeyID) == "" || strings.TrimSpace(cfg.AwsSecretAccessKey) == "" {
return errors.New("AWS credentials missing; refusing to build sigv4 transport")
}
rt, err := sigv4.NewRoundTripper(cfg, http.DefaultTransport) Defensive patterns
Strategy: validation
Validate before calling
// Go: guard before building the round tripper.
func validSigV4(c *sigv4.Config) bool {
if c == nil { return false }
trim := func(s string) string { return strings.TrimSpace(s) }
return trim(c.Region) != "" && trim(c.AwsAccessKeyID) != "" && trim(c.AwsSecretAccessKey) != ""
}
if !validSigV4(cfg) { return errors.New("refusing sigv4: region/access key/secret key incomplete") } Type guard
func isSigV4ConfigComplete(c *sigv4.Config) bool {
if c == nil {
return false
}
return strings.TrimSpace(c.Region) != "" &&
strings.TrimSpace(c.AwsAccessKeyID) != "" &&
strings.TrimSpace(c.AwsSecretAccessKey) != ""
} Try / catch
In Go, wrap sigv4.NewRoundTripper in a check of the returned error and fail configuration-time, not request-time; do not fall back to an unsigned transport on failure.
Prevention
- Trim and assert all three fields non-empty where the Config is built, not where it is used
- Load AWS credentials from one source (env, file, or IMDS) so partial reads are impossible
- Unit-test the config builder with each field missing to confirm it refuses early
When it happens
Trigger: Calling sigv4.NewRoundTripper(&sigv4.Config{Region: "us-east-1"}, transport) from Go code; constructing the Config with fields that contain only whitespace; passing a nil *Config (yields the sibling 'config should not be nil' error); embedding k6 and wiring the sigv4 tripper manually.
Common situations: Go integrations building the SigV4 round tripper themselves; tests that instantiate partial configs; code that reads the three values from different sources (env, file, IMDS) where one read fails and leaves an empty string instead of erroring.
Related errors
- sigv4 seems to be partially configured. All of K6_PROMETHEUS
- stack URL is required to validate token
- invalid size
- empty name provided to SharedArray's constructor
- unsupported exporter protocol %s
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/126d91fd4e7d31fc.
Report an issue: GitHub.