Tencent/WeKnora · error

sandbox: remote docker host %q requires a TLS certificate di

Error message

sandbox: remote docker host %q requires a TLS certificate directory

What it means

ValidateDockerRemoteTLS enforces that remote docker daemons (tcp/http/https schemes) are reached with TLS. Because a remote Engine API that can create containers is effectively root on that host, a TLS certificate directory (client certs/CA) must be configured; an empty tlsCertPath yields this error.

Source

Thrown at internal/sandbox/docker_engine.go:302

}

// ValidateDockerRemoteTLS requires client certificates for a TCP daemon.
// A remote Engine API that accepts container creation is a root shell on
// that host; plaintext tcp://2375 is not an acceptable way to reach it.
// Unix sockets are local to the WeKnora process and do not use TLS.
func ValidateDockerRemoteTLS(host, tlsCertPath string) error {
	trimmed := strings.TrimSpace(host)
	if trimmed == "" {
		return nil
	}
	scheme, _, found := strings.Cut(trimmed, "://")
	if !found {
		return nil
	}
	switch strings.ToLower(scheme) {
	case "tcp", "http", "https":
		if strings.TrimSpace(tlsCertPath) == "" {
			return fmt.Errorf(
				"sandbox: remote docker host %q requires a TLS certificate directory", host)
		}
	}
	return nil
}

// ValidateDockerNetworkMode allows only bridge (egress) and none (no egress).
//
// host and container: modes share another namespace outright, which would put
// sandbox code on the WeKnora host's or a sibling container's network. A
// user-defined network name is refused for the weaker but equally real version
// of the same problem: the usual deployment reaches its daemon through the
// mounted docker.sock, so naming the deployment's own compose network would
// place a sandbox on the same L3 network as Postgres and Redis. Only the
// operator can judge what a given named network exposes, and this value is set
// per workspace config, so it is not theirs to choose.
func ValidateDockerNetworkMode(mode string) error {
	trimmed := strings.TrimSpace(mode)

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Set the TLS certificate directory config field to the path containing ca.pem, cert.pem, and key.pem generated for the daemon
  2. Regenerate client certificates with the daemon's CA if the directory is empty
  3. If the daemon is genuinely local, switch the host to unix:///var/run/docker.sock so the TLS requirement does not apply
  4. Never fall back to plaintext tcp://: the library intentionally requires TLS for remote Engine APIs

Example fix

// before
Docker: {Host: "tcp://build-host:2376"} // no TLS
// after
Docker: {Host: "tcp://build-host:2376", TLSCertPath: "/etc/docker/client-certs"} // contains ca/cert/key.pem
Defensive patterns

Strategy: validation

Validate before calling

if isRemoteHost(cfg.Docker.Host) && strings.TrimSpace(cfg.Docker.TLSCertPath) == "" {
    return fmt.Errorf("remote docker host %s needs TLSCertPath with ca.pem/cert.pem/key.pem", cfg.Docker.Host)
}
if err := sandbox.ValidateDockerRemoteTLS(cfg.Docker.Host, cfg.Docker.TLSCertPath); err != nil { return err }

Type guard

func remoteHostHasTLS(host, tlsCertPath string) bool {
    scheme, _, found := strings.Cut(strings.TrimSpace(host), "://")
    if !found { return true }
    switch strings.ToLower(scheme) { case "tcp", "http", "https": return strings.TrimSpace(tlsCertPath) != "" }
    return true
}

Try / catch

if err := sandbox.ValidateDockerRemoteTLS(cfg.Docker.Host, cfg.Docker.TLSCertPath); err != nil {
    if strings.Contains(err.Error(), "requires a TLS certificate directory") { /* prompt operator for cert dir */ }
    return err
}

Prevention

When it happens

Trigger: Calling ResolveEffectiveConfig (or dockerSettingsFromConfig) with a docker host whose scheme is tcp://, http://, or https:// while the TLS certificate directory field is empty or whitespace-only.

Common situations: Pointing at a remote daemon (tcp://build-host:2376) without setting up the client cert directory; migrating a local unix:// config to a remote host and forgetting the TLS settings; daemons started with plaintext 2375 ports.

Understand the failure class

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/2239e74abd7f8c8a. Report an issue: GitHub.