goharbor/harbor · error

[tencent-tcr.newAdapter] Invalid TCR instance endpoint

Error message

[tencent-tcr.newAdapter] Invalid TCR instance endpoint

What it means

Returned by newAdapter for the Tencent TCR adapter (src/pkg/reg/adapter/tencentcr/adapter.go:113) when the parsed registry URL's host does not contain '.tencentcloudcr.com'. The adapter only operates against TCR instance endpoints because it drives Tencent Cloud APIs keyed off that host; the check is skipped when UTTEST=true for unit tests. Note url.Parse's error is deliberately ignored, so a malformed URL falls through to this host check.

Source

Thrown at src/pkg/reg/adapter/tencentcr/adapter.go:113

**/
var _ adp.Adapter = &adapter{}

func newAdapter(registry *model.Registry) (a *adapter, err error) {
	if !isSecretID(registry.Credential.AccessKey) {
		err = errors.New("[tencent-tcr.newAdapter] Please use SecretId/SecretKey, NOT docker login Username/Password")
		log.Debugf("[tencent-tcr.newAdapter] error=%v", err)
		return
	}

	// Query TCR instance info via endpoint.
	var registryURL *url.URL
	registryURL, _ = url.Parse(registry.URL)

	// only validate registryURL.Host in non-UT scenario
	if os.Getenv("UTTEST") != "true" {
		if !strings.Contains(registryURL.Host, ".tencentcloudcr.com") {
			log.Errorf("[tencent-tcr.newAdapter] errInvalidTcrEndpoint=%v", err)
			return nil, errInvalidTcrEndpoint
		}
	}

	realm, service, err := util.Ping(registry)
	log.Debugf("[tencent-tcr.newAdapter] realm=%s, service=%s error=%v", realm, service, err)
	if err != nil {
		log.Errorf("[tencent-tcr.newAdapter] ping failed. error=%v", err)
		return
	}

	// Create TCR API client
	var tcrCredential = common.NewCredential(registry.Credential.AccessKey, registry.Credential.AccessSecret)
	var cfp = profile.NewClientProfile()
	var client *tcr.Client
	// temp client used to get TCR instance info
	client, err = tcr.NewClient(tcrCredential, regions.Guangzhou, cfp)
	if err != nil {
		return

View on GitHub (pinned to 7b2fd08cc5)

Solutions

  1. Set registry.URL to the TCR instance endpoint shown in the TCR console, e.g. 'https://<name>-<account>.tencentcloudcr.com'.
  2. Verify which adapter factory matches your URL: if the endpoint is not TCR, configure the registry type (docker-registry/harbor/...) accordingly so the tencentcr adapter is not selected.
  3. Check the URL parses cleanly (url.Parse + inspect Host) before constructing the adapter.
  4. If you must use a custom domain in unit tests, set UTTEST=true — never in production.

Example fix

// before
registry.URL = "https://my-mirror.example.com"
adp, err := tencentcr.NewAdapter(registry) // errInvalidTcrEndpoint

// after
registry.URL = "https://myinstance-1250000000.tencentcloudcr.com"
adp, err := tencentcr.NewAdapter(registry)
Defensive patterns

Strategy: validation

Validate before calling

u, err := url.Parse(registry.URL)
if err != nil || u.Host == "" {
	return fmt.Errorf("registry URL %q is not parseable", registry.URL)
}
if !strings.Contains(u.Host, ".tencentcloudcr.com") {
	return fmt.Errorf("%q is not a TCR instance endpoint", u.Host)
}
adapter, err := tencentcr.NewAdapter(registry)

Type guard

func isTcrEndpoint(raw string) bool {
	u, err := url.Parse(raw)
	return err == nil && strings.Contains(u.Host, ".tencentcloudcr.com")
}

Try / catch

a, err := tencentcr.NewAdapter(registry)
if err != nil {
	if strings.Contains(err.Error(), "Invalid TCR instance endpoint") {
		// configuration error: fix registry.URL or select the right adapter type
	}
	return nil, err
}

Prevention

When it happens

Trigger: Creating a tencentcr adapter with registry.URL whose host lacks '.tencentcloudcr.com' — e.g. 'https://hub.docker.com', a custom CDN domain, a URL with a typo, or a URL so malformed that Host parses empty. Only the host substring is examined; scheme and path are irrelevant.

Common situations: Wrong registry type selected in an endpoint config (docker-hub adapter pointed at tencentcr or vice versa); using a private-domain/fronted TCR endpoint; copy-paste errors in the registry URL; trailing text after the host.

Related errors


AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16). Data as JSON: /api/errors/63716250c4c2918c. Report an issue: GitHub.