uber-go/zap · error
ports not allowed with file URLs: got %v
Error message
ports not allowed with file URLs: got %v
What it means
newFileSinkFromURL rejects file:// URLs containing a port. Ports only apply to network endpoints; a port in a file URL signals a confused destination string, so zap rejects it with a targeted message.
Source
Thrown at sink.go:142
// have a factory registered. Zap automatically registers a factory for the
// "file" scheme.
func RegisterSink(scheme string, factory func(*url.URL) (Sink, error)) error {
return _sinkRegistry.RegisterSink(scheme, factory)
}
func (sr *sinkRegistry) newFileSinkFromURL(u *url.URL) (Sink, error) {
if u.User != nil {
return nil, fmt.Errorf("user and password not allowed with file URLs: got %v", u)
}
if u.Fragment != "" {
return nil, fmt.Errorf("fragments not allowed with file URLs: got %v", u)
}
if u.RawQuery != "" {
return nil, fmt.Errorf("query parameters not allowed with file URLs: got %v", u)
}
// Error messages are better if we check hostname and port separately.
if u.Port() != "" {
return nil, fmt.Errorf("ports not allowed with file URLs: got %v", u)
}
if hn := u.Hostname(); hn != "" && hn != "localhost" {
return nil, fmt.Errorf("file URLs must leave host empty or use localhost: got %v", u)
}
return sr.newFileSinkFromPath(u.Path)
}
func (sr *sinkRegistry) newFileSinkFromPath(path string) (Sink, error) {
switch path {
case "stdout":
return nopCloserSink{os.Stdout}, nil
case "stderr":
return nopCloserSink{os.Stderr}, nil
}
return sr.openFile(path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0o666)
}
View on GitHub (pinned to bbd4ecbd87)
Solutions
- Remove the :port component; file URLs must have an empty host or only 'localhost'.
- If you need a network destination, keep the original scheme (tcp/udp or a registered custom sink) rather than file://.
- Use a plain absolute path for file logging.
Example fix
// before
zap.Open("file://localhost:8080/var/log/app.log")
// after
zap.Open("file:///var/log/app.log") Defensive patterns
Strategy: validation
Validate before calling
u, err := url.Parse(dest)
if err == nil && u.Scheme == "file" && u.Port() != "" {
return fmt.Errorf("file URL must not contain a port: %s", dest)
} Try / catch
if _, err := zap.Open(dest); err != nil {
if strings.Contains(err.Error(), "ports not allowed") {
return fmt.Errorf("remove host:port from file URL %q", dest)
}
return err
} Prevention
- Use file:///path with an empty host for local files
- Never re-scheme network URLs (host:port) to file://
- Separate network sink config from file sink config in templates
When it happens
Trigger: Passing file://localhost:8080/var/log/app.log or file://:5432/path to zap.Open; swapping the scheme of a network sink URL to file:// while keeping host:port.
Common situations: Environment-driven sink URLs where LOG_URL like tcp://host:port is re-schemed to file://; templated configs reusing the same host:port pair across sinks.
Related errors
- user and password not allowed with file URLs: got %v
- fragments not allowed with file URLs: got %v
- query parameters not allowed with file URLs: got %v
- file URLs must leave host empty or use localhost: got %v
- must start with a letter
AI-assisted analysis of uber-go/zap@bbd4ecbd87 (2026-08-31).
Data as JSON: /api/errors/db0375735d8f38b5.
Report an issue: GitHub.