goharbor/harbor · error

missing username and/or password

Error message

missing username and/or password

What it means

BasicAuthHandler.Authorize rejects a preheat request when the credential for the provider instance is in BASIC auth mode but its auth data map is empty — there is no username/password pair to build the Authorization header. Note the handler uses the FIRST key of the map as the username and its value as the password, so the map must contain exactly that pair.

Source

Thrown at src/pkg/p2p/preheat/provider/auth/basic_handler.go:40

// BasicAuthHandler handle the basic auth mode.
type BasicAuthHandler struct {
	*BaseHandler
}

// Mode implements @Handler.Mode
func (b *BasicAuthHandler) Mode() string {
	return AuthModeBasic
}

// Authorize implements @Handler.Authorize
func (b *BasicAuthHandler) Authorize(req *http.Request, cred *Credential) error {
	if err := b.BaseHandler.Authorize(req, cred); err != nil {
		return err
	}

	if len(cred.Data) == 0 {
		return errors.New("missing username and/or password")
	}

	key := reflect.ValueOf(cred.Data).MapKeys()[0].String()
	req.SetBasicAuth(key, cred.Data[key])

	return nil
}

View on GitHub (pinned to 7b2fd08cc5)

Solutions

  1. Re-save the instance with non-empty auth_info for BASIC mode: {"auth_mode": "BASIC", "auth_info": {"username": "<password-is-the-value>"}} — key = username, value = password.
  2. After updating, re-run the policy execution.
  3. If the provider needs no auth, switch the instance to auth_mode "NONE" instead of leaving BASIC empty.

Example fix

# before
curl -X POST https://harbor/api/v2.0/p2p/preheat/instances -d '{"name": "dfly", "provider": "dragonfly", "endpoint": "https://dfly.example.com", "auth_mode": "BASIC", "auth_info": {}}'
# after
curl -X POST https://harbor/api/v2.0/p2p/preheat/instances -d '{"name": "dfly", "provider": "dragonfly", "endpoint": "https://dfly.example.com", "auth_mode": "BASIC", "auth_info": {"admin": "s3cret"}}'
Defensive patterns

Strategy: validation

Validate before calling

function validateBasicAuthInfo(authInfo) {
  const entries = Object.entries(authInfo || {});
  if (entries.length === 0) throw new Error('BASIC auth requires {username: password}');
  // only the FIRST key is used as the username — enforce exactly one entry
  if (entries.length !== 1) throw new Error('provide exactly one username:password pair');
}

Type guard

function isBasicCredValid(cred) {
  return cred != null && cred.Data != null && Object.keys(cred.Data).length > 0;
}

Try / catch

Catch errors from instance creation/policy execution mentioning 'missing username and/or password'; re-PUT the instance with a populated auth_info map, then re-run the execution.

Prevention

When it happens

Trigger: Creating/using a preheat instance (POST /api/v2.0/p2p/preheat/instances) with auth_mode "BASIC" and empty or missing auth_info; auth_info that failed to JSON-decode into a map; policy execution against such an instance hits Authorize on the first outbound request.

Common situations: Instance registration forms where auth mode was selected but credentials never entered; automation storing auth_info as a string or array instead of an object; credentials removed by a later PUT to the instance that emptied auth_info.

Related errors


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