Tencent/WeKnora · error

sandbox: docker host %q must include a scheme (unix:// or tc

Error message

sandbox: docker host %q must include a scheme (unix:// or tcp://)

What it means

ValidateDockerHost checks that a configured docker host string is usable by the sandbox backend. After trimming, the host must contain a "://" separator separating a scheme from an address; bare values like "localhost:2375" or "/var/run/docker.sock" are rejected because the client cannot infer the transport.

Source

Thrown at internal/sandbox/docker_engine.go:266

	default:
		return false
	}
}

// ValidateDockerHost checks a daemon endpoint before it is stored or dialled.
//
// A TCP endpoint gets the same outbound treatment as any other workspace-
// supplied URL: a daemon socket accepts container creation, so an admin who
// can point it anywhere can make WeKnora talk to an arbitrary internal
// service. Unix sockets are local by definition and only have to be absolute.
func ValidateDockerHost(host string, allowPrivate bool) error {
	trimmed := strings.TrimSpace(host)
	if trimmed == "" {
		return nil
	}
	scheme, address, found := strings.Cut(trimmed, "://")
	if !found {
		return fmt.Errorf(
			"sandbox: docker host %q must include a scheme (unix:// or tcp://)", host)
	}
	switch strings.ToLower(scheme) {
	case "unix":
		if !strings.HasPrefix(address, "/") {
			return fmt.Errorf("sandbox: docker unix socket path %q must be absolute", address)
		}
		return nil
	case "tcp", "http", "https":
		// The guard speaks HTTP; the daemon's TCP endpoint is an HTTP
		// endpoint, so the check is the same one every other backend gets.
		return ValidateOutboundURLWithPolicy(
			"http://"+address, OutboundURLPolicy{AllowPrivate: allowPrivate},
		)
	default:
		return fmt.Errorf("sandbox: unsupported docker host scheme %q", scheme)
	}
}

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Prefix the host with a scheme: use unix:///path/to/socket for local sockets or tcp://host:port for remote daemons
  2. Prefer https:// (or tcp:// with TLS configured) for remote daemons over plaintext tcp://
  3. Re-run ResolveEffectiveConfig after fixing to catch any subsequent validation errors (TLS, network mode)
  4. Note that empty/whitespace hosts pass (they fall back to defaults) — only non-empty scheme-less strings error

Example fix

// before
Host: "localhost:2375"
// after
Host: "tcp://localhost:2375" // or "unix:///var/run/docker.sock"
Defensive patterns

Strategy: validation

Validate before calling

h := strings.TrimSpace(cfg.Docker.Host)
if h != "" && !strings.Contains(h, "://") {
    return fmt.Errorf("docker host %q needs a scheme: unix:// or tcp://", h)
}
if err := sandbox.ValidateDockerHost(h, true); err != nil { return err }

Type guard

func hasValidHostScheme(host string) bool {
    t := strings.TrimSpace(host)
    if t == "" { return true }
    _, _, ok := strings.Cut(t, "://")
    return ok
}

Try / catch

if err := sandbox.ValidateDockerHost(cfg.Docker.Host, allowPrivate); err != nil {
    if strings.Contains(err.Error(), "must include a scheme") { cfg.Docker.Host = "unix://" + cfg.Docker.Host }
    return err
}

Prevention

When it happens

Trigger: Setting the docker host config field to a value without a scheme — e.g. "localhost:2375", "127.0.0.1:2375", or a bare socket path — and calling ResolveEffectiveConfig or TestValidateDockerHost.

Common situations: Copying DOCKER_HOST-style values from tooling that accepts bare hosts; writing just the socket path instead of unix:///var/run/docker.sock; omitting tcp:// from a remote daemon address.

Related errors


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