{"record":{"id":"5078ae6ff065e183","repo":"grafana/k6","slug":"urltemplate-is-required","errorCode":null,"errorMessage":"urlTemplate is required","messagePattern":"urlTemplate is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/secretsource/url/url.go","lineNumber":30,"sourceCode":"\t\"math/rand\" // nosemgrep: math-random-used // This is being used for retry jitter\n\t\"net/http\"\n\t\"net/url\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/sirupsen/logrus\"\n\t\"github.com/tidwall/gjson\"\n\t\"gopkg.in/guregu/null.v3\"\n\n\t\"go.k6.io/k6/v2/lib\"\n\t\"go.k6.io/k6/v2/lib/fsext\"\n\t\"go.k6.io/k6/v2/lib/types\"\n\t\"go.k6.io/k6/v2/secretsource\"\n\t\"golang.org/x/time/rate\"\n)\n\nvar (\n\terrMissingURLTemplate = errors.New(\"urlTemplate is required\")\n\terrFailedToGetSecret  = errors.New(\"failed to get secret\")\n)\n\n// extConfig holds the configuration for URL-based secrets.\ntype extConfig struct {\n\t// URLTemplate is a URL template with {key} placeholder\n\t// Example: \"https://api.example.com/secrets/{key}\"\n\tURLTemplate string `json:\"urlTemplate\"`\n\n\t// Headers to include in the request (e.g., Authorization headers)\n\tHeaders map[string]string `json:\"headers\"`\n\n\t// Method is the HTTP method to use (default: GET)\n\tMethod null.String `json:\"method\"`\n\n\t// ResponsePath is a JSON path to extract the secret value from the response\n\t// Use dot notation for nested fields (e.g., \"data.value\")\n\t// If empty, the entire response body is treated as the secret","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/internal/secretsource/url/url.go#L12-L48","documentation":"Returned by the URL secret source (validateURLTemplate) when the consolidated config has an empty urlTemplate. The URL secret source builds requests from a template with a {key} placeholder (e.g. https://api.example.com/secrets/{key}); without a template it cannot form any request, so construction fails with the sentinel error errMissingURLTemplate.","triggerScenarios":"Registering the url secret source via --secret-source=url=... without a urlTemplate parameter; a JSON config file for the source that omits urlTemplate; K6_SECRET_SOURCE_URL_URL_TEMPLATE exported as empty; passing only headers (e.g. Authorization) but no template.","commonSituations":"First-time setup of HTTP-backed secrets where the user wires auth but forgets the template; config files copied from examples that comment out the template line; templating systems that drop the value when the backing variable is undefined.","solutions":["Provide the template: --secret-source=url=urlTemplate=https://api.example.com/secrets/{key}","Or set it in the JSON config: {\"urlTemplate\": \"https://api.example.com/secrets/{key}\"}","Ensure the template contains the {key} placeholder (a follow-up validation rejects templates without it)"],"exampleFix":"# before\nk6 run --secret-source=url=header.AUTHORIZATION=Bearer\ntoken script.js\n# urlTemplate omitted -> urlTemplate is required\n\n# after\nk6 run --secret-source=url=urlTemplate=https://api.example.com/secrets/{key},header.AUTHORIZATION=\"Bearer $TOKEN\" script.js","handlingStrategy":"validation","validationCode":"# Require a template containing {key} before registering the url secret source:\ncase \"${TEMPLATE:-}\" in\n  \"\"|*[!{key}]*) echo \"urlTemplate is required and must contain {key}\"; exit 1;;\nesac\nk6 run --secret-source=url=urlTemplate=\"$TEMPLATE\" script.js","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always pass urlTemplate as the first parameter when registering the url secret source","Keep a validated example config in the repo and CI-lint it (template present, contains {key}, URL parses)","Do not ship commented-out template lines in examples; readers copy them verbatim"],"tags":["k6","secrets","url","template","config"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}