larksuite/cli · error
proxy plugin transport unavailable: http.DefaultTransport is
Error message
proxy plugin transport unavailable: http.DefaultTransport is %T, want *http.Transport
What it means
The proxy plugin transport builder expects http.DefaultTransport to be a *http.Transport so it can clone it; a test or embedding host replaced it with a custom RoundTripper implementation. The builder fails closed with a blocked transport rather than allowing direct egress, since it cannot safely apply proxy settings to an unknown RoundTripper.
Source
Thrown at internal/transport/transport.go:33
var proxyPluginTransport = sync.OnceValue(buildProxyPluginTransport)
// cachedBlockedTransport is a fail-closed transport cached on first use when
// the proxy plugin config exists but is invalid. This avoids cloning
// http.DefaultTransport on every pluginTransport call.
var cachedBlockedTransport = sync.OnceValue(buildBlockedTransport)
func buildBlockedTransport() http.RoundTripper {
return failClosedTransport(fmt.Errorf("proxy plugin config is invalid: %w", loadErr))
}
func buildProxyPluginTransport() http.RoundTripper {
def, ok := http.DefaultTransport.(*http.Transport)
if !ok {
// Cannot clone the stdlib transport. Fail closed with a concrete
// *http.Transport (not a bare RoundTripper) so downcasting callers such
// as Fallback cannot silently degrade this into a
// direct-egress transport.
return failClosedTransport(fmt.Errorf("proxy plugin transport unavailable: http.DefaultTransport is %T, want *http.Transport", http.DefaultTransport))
}
cfg, err := Load()
if err != nil {
// Fail closed: config file exists but is malformed/unreadable — do not
// silently fall back to direct egress.
return blockedTransport(def, fmt.Errorf("proxy plugin config is invalid: %w", err))
}
if cfg == nil || !cfg.Enabled() {
return def
}
t, err := cfg.ApplyToTransport(def)
if err != nil {
// Fail closed: do not silently fall back to direct egress when the
// operator explicitly enabled proxy plugin mode.
return blockedTransport(def, fmt.Errorf("proxy plugin enabled but config is invalid: %w", err))
}
return tView on GitHub (pinned to 7fd6ef3c07)
Solutions
- Remove or defer the http.DefaultTransport override so the stdlib *http.Transport is in place when the CLI initializes.
- If the override is required, install a *http.Transport (e.g. a clone of the default) instead of a bare RoundTripper.
- Restore http.DefaultTransport with t.Cleanup/defer in tests before exercising CLI transport setup.
Example fix
// before
http.DefaultTransport = myMetricsRoundTripper{}
// after
if def, ok := http.DefaultTransport.(*http.Transport); ok {
cloned := def.Clone()
cloned.Proxy = nil
http.DefaultTransport = &instrumentedTransport{base: cloned}
} Defensive patterns
Strategy: type-guard
Validate before calling
if _, ok := http.DefaultTransport.(*http.Transport); !ok {
log.Fatal("http.DefaultTransport must remain a *http.Transport for the CLI proxy plugin")
} Type guard
func defaultTransportIsClonable() bool {
_, ok := http.DefaultTransport.(*http.Transport)
return ok
} Try / catch
if tr, err := pluginTransport(); err != nil && strings.Contains(err.Error(), "want *http.Transport") {
log.Fatalf("remove the http.DefaultTransport override in this process: %v", err)
} Prevention
- Avoid globally replacing http.DefaultTransport in hosts embedding the CLI.
- In tests, restore http.DefaultTransport with defer/t.Cleanup.
- Wrap *http.Transport clones rather than bare RoundTripper implementations.
When it happens
Trigger: Code (usually tests like TestBuildProxyPluginTransport_NonTransportDefaultFailsClosed, or a host app) assigns a non-*http.Transport to http.DefaultTransport, then the proxy plugin path builds its transport.
Common situations: Libraries that globally override http.DefaultTransport (metrics, mocking, custom dialers) running in-process with the CLI; tests swapping DefaultTransport without restoring it.
Related errors
- proxy plugin config is invalid: %w
- proxy plugin enabled but config is invalid: %w
- failed to get HTTP client for user_info: %w
- failed to parse TAT response (HTTP %d): %w
- invalid proxy plugin config %q: %w
AI-assisted analysis of larksuite/cli@7fd6ef3c07 (2026-09-04).
Data as JSON: /api/errors/6017693e10c50e24.
Report an issue: GitHub.