docker/cli · error

empty string specified for links

Error message

empty string specified for links

What it means

Thrown by opts.ParseLink when the input string is empty. ParseLink parses Docker's legacy container-link format ("name:alias") used by --link; an empty string has no container name to resolve, so it is rejected outright. This guard sits at the very top of the function before any splitting occurs.

Solutions

  1. Omit the --link flag entirely when no link is needed.
  2. Ensure the link variable is non-empty before passing it: guard with a length/emptiness check.
  3. If building Links programmatically, filter out empty strings from the slice before submission.

Example fix

// before
name, alias, err := opts.ParseLink("")
// after
if l == "" {
    return errors.New("link must not be empty")
}
name, alias, err := opts.ParseLink(l)
Defensive patterns

Strategy: validation

Validate before calling

if strings.TrimSpace(link) == "" {
    return fmt.Errorf("link must not be empty")
}
name, alias, err := opts.ParseLink(link)

Try / catch

name, alias, err := opts.ParseLink(link)
if err != nil {
    // log err; skip this link or abort
    return err
}

Prevention

When it happens

Trigger: Calling opts.ParseLink(""), passing --link "" to docker run/create, or constructing a HostConfig.Links slice that contains an empty element.

Common situations: Shell scripting docker run with an unset/empty link variable, e.g. LINK=""; docker run --link "$LINK:alias". Also happens when programmatically building the Links slice from filtered or missing data.

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/71319f042dc999f7. Report an issue: GitHub.

Appendix: source

Thrown at opts/opts.go:374

}

// ParseCPUs takes a string ratio and returns an integer value of nano cpus
func ParseCPUs(value string) (int64, error) {
	cpu, ok := new(big.Rat).SetString(value)
	if !ok {
		return 0, fmt.Errorf("failed to parse %v as a rational number", value)
	}
	nano := cpu.Mul(cpu, big.NewRat(1e9, 1))
	if !nano.IsInt() {
		return 0, errors.New("value is too precise")
	}
	return nano.Num().Int64(), nil
}

// ParseLink parses and validates the specified string as a link format (name:alias)
func ParseLink(val string) (string, string, error) {
	if val == "" {
		return "", "", errors.New("empty string specified for links")
	}
	// We expect two parts, but restrict to three to allow detecting invalid formats.
	arr := strings.SplitN(val, ":", 3)

	// TODO(thaJeztah): clean up this logic!!
	if len(arr) > 2 {
		return "", "", errors.New("bad format for links: " + val)
	}
	// TODO(thaJeztah): this should trim the "/" prefix as well??
	if len(arr) == 1 {
		return val, val, nil
	}
	// This is kept because we can actually get a HostConfig with links
	// from an already created container and the format is not `foo:bar`
	// but `/foo:/c1/bar`
	if strings.HasPrefix(arr[0], "/") {
		// TODO(thaJeztah): clean up this logic!!
		_, alias := path.Split(arr[1])

View on GitHub (pinned to 4f84911bfe)