{"record":{"id":"cbcb9af60edaf70c","repo":"goharbor/harbor","slug":"missing-username-and-or-password","errorCode":null,"errorMessage":"missing username and/or password","messagePattern":"missing username and/or password","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/pkg/p2p/preheat/provider/auth/basic_handler.go","lineNumber":40,"sourceCode":"\n// BasicAuthHandler handle the basic auth mode.\ntype BasicAuthHandler struct {\n\t*BaseHandler\n}\n\n// Mode implements @Handler.Mode\nfunc (b *BasicAuthHandler) Mode() string {\n\treturn AuthModeBasic\n}\n\n// Authorize implements @Handler.Authorize\nfunc (b *BasicAuthHandler) Authorize(req *http.Request, cred *Credential) error {\n\tif err := b.BaseHandler.Authorize(req, cred); err != nil {\n\t\treturn err\n\t}\n\n\tif len(cred.Data) == 0 {\n\t\treturn errors.New(\"missing username and/or password\")\n\t}\n\n\tkey := reflect.ValueOf(cred.Data).MapKeys()[0].String()\n\treq.SetBasicAuth(key, cred.Data[key])\n\n\treturn nil\n}\n","sourceCodeStart":22,"sourceCodeEnd":48,"githubUrl":"https://github.com/goharbor/harbor/blob/7b2fd08cc568955cca339afeefab27372840d936/src/pkg/p2p/preheat/provider/auth/basic_handler.go#L22-L48","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\ncurl -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\": {}}'\n# after\ncurl -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\"}}'","handlingStrategy":"validation","validationCode":"function validateBasicAuthInfo(authInfo) {\n  const entries = Object.entries(authInfo || {});\n  if (entries.length === 0) throw new Error('BASIC auth requires {username: password}');\n  // only the FIRST key is used as the username — enforce exactly one entry\n  if (entries.length !== 1) throw new Error('provide exactly one username:password pair');\n}","typeGuard":"function isBasicCredValid(cred) {\n  return cred != null && cred.Data != null && Object.keys(cred.Data).length > 0;\n}","tryCatchPattern":"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.","preventionTips":["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."],"tags":["p2p-preheat","basic-auth","credentials","provider","harbor"],"backgroundTag":null,"analyzedSha":"7b2fd08cc568955cca339afeefab27372840d936","analyzedAt":"2026-08-16T00:00:10.961Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}