caddyserver/caddy · error

failed to load network_proxy module: %v

Error message

failed to load network_proxy module: %v

What it means

When a `network_proxy` module (or the deprecated `forward_proxy_url`, which is converted to one) is configured on the HTTP transport, Caddy loads it via `caddyCtx.LoadModule(h, "NetworkProxyRaw")`. Any error from module instantiation (unknown module ID, bad inline JSON, failed Provision) is wrapped with this message and transport creation fails.

Source

Thrown at modules/caddyhttp/reverseproxy/httptransport.go:379

				writeTimeout: time.Duration(h.WriteTimeout),
				logger:       caddyCtx.Logger(),
			}
		}

		return conn, nil
	}

	// negotiate any HTTP/SOCKS proxy for the HTTP transport
	proxy := http.ProxyFromEnvironment
	if h.ForwardProxyURL != "" {
		caddyCtx.Logger().Warn("forward_proxy_url is deprecated; use network_proxy instead")
		u := network.ProxyFromURL{URL: h.ForwardProxyURL}
		h.NetworkProxyRaw = caddyconfig.JSONModuleObject(u, "from", "url", nil)
	}
	if len(h.NetworkProxyRaw) != 0 {
		proxyMod, err := caddyCtx.LoadModule(h, "NetworkProxyRaw")
		if err != nil {
			return nil, fmt.Errorf("failed to load network_proxy module: %v", err)
		}
		if m, ok := proxyMod.(caddy.ProxyFuncProducer); ok {
			proxy = m.ProxyFunc()
		} else {
			return nil, fmt.Errorf("network_proxy module is not `(func(*http.Request) (*url.URL, error))``")
		}
	}
	// we need to keep track if a proxy is used for a request
	proxyWrapper := func(req *http.Request) (*url.URL, error) {
		if proxy == nil {
			return nil, nil
		}
		u, err := proxy(req)
		if u == nil || err != nil {
			return u, err
		}
		// there must be a proxy for this request
		caddyhttp.SetVar(req.Context(), proxyVarKey, u)

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Read the wrapped error (%v) — it names the real cause such as unknown module or unmarshal failure
  2. Fix the module name in network_proxy's "from"/protocol field to a registered module (e.g. from: "url")
  3. If using a custom build, ensure the package providing the module is imported (modules/standard or your own imports)
  4. Run `caddy list-modules` and confirm the network proxy module appears

Example fix

// JSON before
"network_proxy": {"from": "http"}
// JSON after
"network_proxy": {"from": "url", "url": "http://proxy.internal:3128"}
Defensive patterns

Strategy: validation

Validate before calling

// before deploy, confirm the module exists in this build
// caddy list-modules | grep caddy.http.transport.proxy
if !moduleRegistered("caddy.http.transport.proxy.url") {
	return errors.New("network_proxy module missing from build")
}

Prevention

When it happens

Trigger: Setting `network_proxy` in JSON with a typo'd module name or invalid inline config; using forward_proxy_url whose auto-generated module object fails to load; a custom build missing the legacy import for the network_proxy module namespace.

Common situations: Custom Caddy binaries built without the `caddy.modules.logging`-style import for the http transport network proxy modules; version drift where module IDs were renamed; malformed JSON hand-edited configs.

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/4d91bb2b77c5eb00. Report an issue: GitHub.