larksuite/cli · error
invalid %s %q: missing host
Error message
invalid %s %q: missing host
What it means
Security hardening: the proxy plugin only allows a loopback proxy on 127.0.0.1, preventing accidental cross-machine proxying of CLI credentials and traffic. Any other hostname or IP — including localhost, ::1, 0.0.0.0, or a LAN IP — is rejected with a redacted address in the message.
Source
Thrown at internal/transport/config.go:204
// proxyURL validates the fixed configured proxy configuration and returns its URL.
func (c *Config) proxyURL() (*url.URL, error) {
raw := strings.TrimSpace(c.Proxy)
if raw == "" {
return nil, fmt.Errorf("%s is empty", envvars.CliProxyAddress)
}
redacted := redactProxyURL(raw)
u, err := url.Parse(raw)
if err != nil {
// Do not wrap the raw url.Parse error: its string embeds the original
// URL, which can contain userinfo (user:password). Return a redacted,
// generic message instead.
return nil, fmt.Errorf("invalid %s %q: malformed URL", envvars.CliProxyAddress, redacted)
}
if u.Scheme != "http" {
return nil, fmt.Errorf("invalid %s %q: scheme must be http", envvars.CliProxyAddress, redacted)
}
if u.Host == "" {
return nil, fmt.Errorf("invalid %s %q: missing host", envvars.CliProxyAddress, redacted)
}
// Security hardening: only allow a loopback proxy. This prevents accidental
// cross-machine proxying of credentials/traffic.
if u.Hostname() != "127.0.0.1" {
return nil, fmt.Errorf("invalid %s %q: host must be 127.0.0.1", envvars.CliProxyAddress, redacted)
}
if u.Port() == "" {
return nil, fmt.Errorf("invalid %s %q: explicit port is required", envvars.CliProxyAddress, redacted)
}
if u.Path != "" {
return nil, fmt.Errorf("invalid %s %q: path is not allowed", envvars.CliProxyAddress, redacted)
}
if u.RawQuery != "" {
return nil, fmt.Errorf("invalid %s %q: query is not allowed", envvars.CliProxyAddress, redacted)
}
if u.Fragment != "" {
return nil, fmt.Errorf("invalid %s %q: fragment is not allowed", envvars.CliProxyAddress, redacted)
}View on GitHub (pinned to 7fd6ef3c07)
Solutions
- Use the literal loopback IP with an explicit port: `export LARKSUITE_CLI_PROXY_ADDRESS=http://127.0.0.1:8080` (localhost is NOT accepted).
- If your proxy runs elsewhere, run a local forwarder on 127.0.0.1 that relays to it, and point the variable at the local port.
- Check the hostname portion exactly matches 127.0.0.1 — no brackets, no name: `echo $LARKSUITE_CLI_PROXY_ADDRESS`.
- Update proxy_config.json's LARKSUITE_CLI_PROXY_ADDRESS the same way if configured via file.
Example fix
// before export LARKSUITE_CLI_PROXY_ADDRESS=http://localhost:8080 // after export LARKSUITE_CLI_PROXY_ADDRESS=http://127.0.0.1:8080
Defensive patterns
Strategy: validation
Validate before calling
host="${LARKSUITE_CLI_PROXY_ADDRESS#http://}"; host="${host%%:*}"
if [ "$host" != "127.0.0.1" ]; then echo "proxy host must be 127.0.0.1, got: $host" >&2; fi Prevention
- Always use the literal IP 127.0.0.1 — 'localhost' and '::1' are rejected.
- For a remote/container proxy, run a local relay bound to 127.0.0.1 and point the variable at it.
- This restriction is intentional credential-safety hardening; don't work around it by proxying other machines' traffic.
- Keep the address in one place (env var or proxy_config.json) to avoid drift.
When it happens
Trigger: LARKSUITE_CLI_PROXY_ADDRESS set to `http://localhost:8080`, `http://[::1]:8080`, `http://192.168.1.10:8080`, or a DNS name, while proxy mode is enabled; ApplyToTransport fails during startup.
Common situations: Assuming 'localhost' is accepted; pointing at a proxy running in a container/VM by its IP; copying a corporate proxy address that isn't loopback.
Related errors
- invalid %s %q: scheme must be http
- invalid proxy plugin config %q: %w
- invalid %s %q (want true/false/1/0)
- %s is empty
- invalid %s %q: malformed URL
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/182c79c5dbb8460f.
Report an issue: GitHub.