caddyserver/caddy · error

URL is required

Error message

URL is required

What it means

Returned by HTTPCertGetter.Provision (the tls.get_certificate.http module, i.e. 'get_certificate http <url>' in a Caddyfile) when the URL field is empty. The module fetches a certificate bundle over HTTP at handshake time, so an endpoint is mandatory; provisioning fails fast rather than letting every handshake fail later.

Source

Thrown at modules/caddytls/certmanagers.go:124

	// (No Content). Error statuses will indicate that the manager is
	// capable of providing a certificate but was unable to.
	URL string `json:"url,omitempty"`

	ctx context.Context
}

// CaddyModule returns the Caddy module information.
func (hcg HTTPCertGetter) CaddyModule() caddy.ModuleInfo {
	return caddy.ModuleInfo{
		ID:  "tls.get_certificate.http",
		New: func() caddy.Module { return new(HTTPCertGetter) },
	}
}

func (hcg *HTTPCertGetter) Provision(ctx caddy.Context) error {
	hcg.ctx = ctx
	if hcg.URL == "" {
		return fmt.Errorf("URL is required")
	}
	return nil
}

func (hcg HTTPCertGetter) GetCertificate(ctx context.Context, hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
	sigs := make([]string, len(hello.SignatureSchemes))
	for i, sig := range hello.SignatureSchemes {
		sigs[i] = fmt.Sprintf("%x", uint16(sig)) // you won't believe what %x uses if the val is a Stringer
	}
	suites := make([]string, len(hello.CipherSuites))
	for i, cs := range hello.CipherSuites {
		suites[i] = fmt.Sprintf("%x", cs)
	}

	parsed, err := url.Parse(hcg.URL)
	if err != nil {
		return nil, err
	}

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Add the URL: 'get_certificate http https://certs.example.com/certs' in the Caddyfile
  2. If using JSON, ensure the module object has a non-empty "url" value
  3. Run 'caddy adapt --config Caddyfile --adapter caddyfile' to confirm the URL survives adaptation
  4. Check for typos that make the URL parse as a block instead of an argument

Example fix

# before
get_certificate http

# after
get_certificate http https://certs.example.com/certs
Defensive patterns

Strategy: validation

Validate before calling

# Adapt + inspect before running:
caddy adapt --config Caddyfile --adapter caddyfile 2>/dev/null | jq '.apps.tls.certificates.get_certificate // empty'

Prevention

When it happens

Trigger: Configuring get_certificate http with no URL argument, or JSON config where tls.get_certificate.http has an empty/missing "url" key. In Caddyfile syntax: 'get_certificate http' with the URL line missing or mistyped as a subdirective.

Common situations: Hand-written Caddyfile omits the URL; JSON config built programmatically leaves the field empty; a template/automation pipeline that was supposed to inject the URL produced an empty string.

Related errors


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