goharbor/harbor · error

empty realm

Error message

empty realm

What it means

Returned by NewClient when the GitLab registry's /v2/ ping succeeds but the WWW-Authenticate challenge contains no realm URL. Without a realm, the client cannot build the token-auth endpoint, so client construction is aborted. It indicates the registry did not advertise a usable OAuth2/token realm (misconfigured registry or non-bearer auth setup).

Solutions

  1. Verify the GitLab registry URL points to the container registry endpoint and answers /v2/ with a bearer challenge
  2. Check that GitLab's container registry token auth is enabled and the realm is advertised
  3. Confirm the registry is a GitLab registry; other registries need a different adapter
  4. Capture the /v2/ response headers to inspect the WWW-Authenticate challenge
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at src/pkg/reg/adapter/gitlab/client.go:49 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at src/pkg/reg/adapter/gitlab/client.go:49

	"github.com/goharbor/harbor/src/pkg/reg/util"
)

// Client is a client to interact with GitLab
type Client struct {
	client   *common_http.Client
	url      string
	username string
	token    string
}

// NewClient creates a new GitLab client.
func NewClient(registry *model.Registry) (*Client, error) {
	realm, _, err := util.Ping(registry)
	if err != nil && !liberrors.IsChallengesUnsupportedErr(err) {
		return nil, err
	}
	if realm == "" {
		return nil, fmt.Errorf("empty realm")
	}
	location, err := url.Parse(realm)
	if err != nil {
		return nil, err
	}
	client := &Client{
		url:      location.Scheme + "://" + location.Host,
		username: registry.Credential.AccessKey,
		token:    registry.Credential.AccessSecret,
		client: common_http.NewClient(
			&http.Client{
				Transport: common_http.GetHTTPTransport(
					common_http.WithInsecure(registry.Insecure),
					common_http.WithCACert(registry.CACertificate),
				),
				Timeout: config.RegistryHTTPClientTimeout(),
			}),
	}

View on GitHub (pinned to 7b2fd08cc5)