docker/cli · error · invalidParameterErr

unable to parse server address

Error message

unable to parse server address: %w

What it means

Returned by Service.Auth when url.Parse fails on the normalized authConfig.ServerAddress (an https:// prefix is prepended if no scheme present). The parse error is wrapped with invalidParam. This guards against malformed server addresses before endpoint lookup.

Solutions

  1. Correct the server address to a clean host[:port] (e.g. `registry.example.com:5000`).
  2. If including a scheme, use http:// or https://; avoid unsupported schemes.
  3. Sanitize/validate the address before passing it to Auth.

Example fix

// before
auth.ServerAddress = "registry example com"
// after
auth.ServerAddress = "registry.example.com:5000"
Defensive patterns

Strategy: validation

Validate before calling

test := authConfig.ServerAddress
if !strings.HasPrefix(test, "http://") && !strings.HasPrefix(test, "https://") { test = "https://" + test }
if _, err := url.Parse(test); err != nil { return fmt.Errorf("bad server address: %w", err) }

Prevention

When it happens

Trigger: Calling Auth with a ServerAddress that is not a valid URL after scheme normalization — illegal characters, invalid escaping, malformed host.

Common situations: User types a registry address with spaces/special chars; programmatic AuthConfig with an unescaped address; trailing junk in config; using a value intended for another field.

Understand the failure class

Related errors


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

Appendix: source

Thrown at internal/registry/service.go:45

		return nil, err
	}
	return &Service{config: config}, nil
}

// Auth contacts the public registry with the provided credentials,
// and returns OK if authentication was successful.
// It can be used to verify the validity of a client's credentials.
func (s *Service) Auth(ctx context.Context, authConfig *registry.AuthConfig, userAgent string) (token string, _ error) {
	registryHostName := IndexHostname

	if authConfig.ServerAddress != "" {
		serverAddress := authConfig.ServerAddress
		if !strings.HasPrefix(serverAddress, "https://") && !strings.HasPrefix(serverAddress, "http://") {
			serverAddress = "https://" + serverAddress
		}
		u, err := url.Parse(serverAddress)
		if err != nil {
			return "", invalidParam(fmt.Errorf("unable to parse server address: %w", err))
		}
		registryHostName = u.Host
	}

	// Lookup endpoints for authentication.
	endpoints, err := s.Endpoints(ctx, registryHostName)
	if err != nil {
		if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
			return "", err
		}
		return "", invalidParam(err)
	}

	var lastErr error
	for _, endpoint := range endpoints {
		authToken, err := loginV2(ctx, authConfig, endpoint, userAgent)
		if err != nil {
			if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) || errdefs.IsUnauthorized(err) {

View on GitHub (pinned to 4f84911bfe)