{"record":{"id":"9ec0fcf1dec7a987","repo":"nats-io/nats-server","slug":"error-parsing-s-url-q","errorCode":null,"errorMessage":"error parsing %s url [%q]","messagePattern":"error parsing (.+?) url \\[%q\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/opts.go","lineNumber":2269,"sourceCode":"\t\tdd[sURL] = true\n\t\turl, err := parseURL(sURL, typ)\n\t\tif err != nil {\n\t\t\terr := &configErr{tk, err.Error()}\n\t\t\terrors = append(errors, err)\n\t\t\tcontinue\n\t\t}\n\t\turls = append(urls, url)\n\t}\n\treturn urls, errors\n}\n\nfunc parseURL(u string, typ string) (*url.URL, error) {\n\turlStr := strings.TrimSpace(u)\n\turl, err := url.Parse(urlStr)\n\tif err != nil {\n\t\t// Security note: if it's not well-formed but still reached us, then we're going to log as-is which might include password information here.\n\t\t// If the URL parses, we don't log the credentials ever, but if it doesn't even parse we don't have a sane way to redact.\n\t\treturn nil, fmt.Errorf(\"error parsing %s url [%q]\", typ, urlStr)\n\t}\n\treturn url, nil\n}\n\nfunc parseGateway(v any, o *Options, errors *[]error, warnings *[]error) error {\n\tvar lt token\n\tdefer convertPanicToErrorList(&lt, errors)\n\n\ttk, v := unwrapValue(v, &lt)\n\tgm, ok := v.(map[string]any)\n\tif !ok {\n\t\treturn &configErr{tk, fmt.Sprintf(\"Expected gateway to be a map, got %T\", v)}\n\t}\n\tfor mk, mv := range gm {\n\t\t// Again, unwrap token value if line check is required.\n\t\ttk, mv = unwrapValue(mv, &lt)\n\t\tswitch strings.ToLower(mk) {\n\t\tcase \"name\":","sourceCodeStart":2251,"sourceCodeEnd":2287,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/opts.go#L2251-L2287","documentation":"parseURL in server/opts.go wraps url.Parse failures for typed URLs (monitor/cluster/gateway/auth URLs; typ names the kind). If the string is not even a well-formed URL, the library logs it as-is — including possible credentials — because there is no sane way to redact an unparseable URL. The error names the URL type and the raw string in %q.","triggerScenarios":"Any config URL option (client_advertise, gateway/cluster/auth URLs) containing control characters, spaces, invalid percent-encoding ('%zz'), or other text url.Parse rejects.","commonSituations":"Typos like 'http//host:8222' (missing colon); unescaped special characters in passwords embedded in URLs; newline/space from env substitution; accidental shell-style placeholders.","solutions":["Fix the URL syntax named in the error; note the raw string may contain a password, so rotate any credentials visible in logs.","Percent-encode special characters in embedded passwords (url.QueryEscape/PathEscape).","Remove whitespace/control characters, especially from env-substituted values.","Test the string with url.Parse (or an equivalent validator) offline before putting it into the config."],"exampleFix":"// before\nurl: \"http://user:p@ss%zz@localhost:8222\"\n// after\nurl: \"http://user:p%40ss@localhost:8222\"","handlingStrategy":"validation","validationCode":"u, err := url.Parse(strings.TrimSpace(rawURL))\nif err != nil {\n\treturn fmt.Errorf(\"rejecting malformed %s url before server start: %v\", typ, err)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Percent-encode credentials embedded in URLs.","Trim whitespace and control chars from env-substituted URLs.","Rotate any password that leaks into logs via an unparseable URL."],"tags":["config","url","parsing","credentials"],"backgroundTag":"malformed-url","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}