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
- 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.
- After updating, re-run the policy execution.
- 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
- Validate auth_info shape at instance-registration time in your automation.
- Remember the BASIC handler takes the first map key as username and its value as password — one entry only.
- Use auth_mode NONE when the provider requires no credentials.
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.