{"record":{"id":"1b0494bf258280c0","repo":"caddyserver/caddy","slug":"parsing-listener-address-v","errorCode":null,"errorMessage":"parsing listener address: %v","messagePattern":"parsing listener address: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"admin.go","lineNumber":1401,"sourceCode":"\tif e.Err != nil {\n\t\treturn e.Err.Error()\n\t}\n\treturn e.Message\n}\n\n// parseAdminListenAddr extracts a singular listen address from either addr\n// or defaultAddr, returning the network and the address of the listener.\nfunc parseAdminListenAddr(addr string, defaultAddr string) (NetworkAddress, error) {\n\tinput, err := NewReplacer().ReplaceOrErr(addr, true, true)\n\tif err != nil {\n\t\treturn NetworkAddress{}, fmt.Errorf(\"replacing listen address: %v\", err)\n\t}\n\tif input == \"\" {\n\t\tinput = defaultAddr\n\t}\n\tlistenAddr, err := ParseNetworkAddress(input)\n\tif err != nil {\n\t\treturn NetworkAddress{}, fmt.Errorf(\"parsing listener address: %v\", err)\n\t}\n\tif listenAddr.PortRangeSize() != 1 {\n\t\treturn NetworkAddress{}, fmt.Errorf(\"must be exactly one listener address; cannot listen on: %s\", listenAddr)\n\t}\n\treturn listenAddr, nil\n}\n\n// decodeBase64DERCert base64-decodes, then DER-decodes, certStr.\nfunc decodeBase64DERCert(certStr string) (*x509.Certificate, error) {\n\tderBytes, err := base64.StdEncoding.DecodeString(certStr)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn x509.ParseCertificate(derBytes)\n}\n\ntype loggableURLArray []*url.URL\n","sourceCodeStart":1383,"sourceCodeEnd":1419,"githubUrl":"https://github.com/caddyserver/caddy/blob/50e54ee279aa1e504fe218ca49ab6ae16c100410/admin.go#L1383-L1419","documentation":"After placeholder replacement, parseAdminListenAddr passes the admin address to ParseNetworkAddress. If the string is not a valid network address (network prefix, host, port), parsing fails and the error is wrapped as 'parsing listener address'. The admin endpoint accepts exactly one address, so even syntactically valid multi-address forms will surface here or in the subsequent port-range check.","triggerScenarios":"Admin listen values like 'localhost:20a0' (non-numeric port), 'unix/' without a socket path, 'tcp/localhost:notaport', an empty host with ':2019:extra', or a network Caddy does not recognize (e.g. 'foobar/localhost:2019'). Triggered during 'caddy run'/'caddy start' or any admin config load that changes Admin.Listen.","commonSituations":"Typos in the admin block of a Caddyfile; copy-pasting an HTTP site address (with scheme or path, e.g. 'https://localhost:2019') into the admin directive; forgetting the port; using a unix socket path without the 'unix/' network prefix.","solutions":["Correct the address to the form [network/]host:port, e.g. 'localhost:2019' or 'unix//run/caddy/admin.sock'.","Remove URL-style components — no scheme, no path: 'admin localhost:2019', not 'admin https://localhost:2019'.","For unix sockets use the unix network prefix: admin unix//run/caddy/admin.sock.","Validate the address with caddy adapt (or ParseNetworkAddress in a scratch program) before deploying."],"exampleFix":"// before\nadmin https://localhost:2019\n\n// after\nadmin localhost:2019","handlingStrategy":"validation","validationCode":"if _, err := caddy.ParseNetworkAddress(adminAddr); err != nil {\n    return fmt.Errorf(\"invalid admin address %q: %w\", adminAddr, err)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use the [network/]host:port form; never a URL with scheme or path.","Validate the admin block with caddy adapt && caddy validate before deploy.","For unix sockets always prefix with unix/."],"tags":["caddy","admin-api","config","network-address","validation"],"backgroundTag":null,"analyzedSha":"50e54ee279aa1e504fe218ca49ab6ae16c100410","analyzedAt":"2026-08-15T09:20:21.641Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}