goharbor/harbor · error · github.com/goharbor/harbor/src/lib/errors.Error
BAD_REQUEST
BAD_REQUEST
Error message
unknown namespace
What it means
The robot controller's toScope (src/controller/robot/controller.go:365) converts a Permission into an access scope. For kind 'system' (LEVELSYSTEM) the namespace must be exactly '/'; any other namespace value is rejected as unknown with BAD_REQUEST (HTTP 400). Project-level permissions use the project name or '*' instead.
Source
Thrown at src/controller/robot/controller.go:365
if !ok {
log.Debugf("got no namespace from the resource %s", scope)
return "", "", errors.Errorf("got no namespace from the resource %s", scope)
}
pro, err := d.proMgr.Get(ctx, ns.Identity())
if err != nil {
return "", "", err
}
namespace = pro.Name
}
return
}
// toScope ...
func (d *controller) toScope(ctx context.Context, p *Permission) (string, error) {
switch p.Kind {
case LEVELSYSTEM:
if p.Namespace != "/" {
return "", errors.New(nil).WithMessage("unknown namespace").WithCode(errors.BadRequestCode)
}
return SCOPESYSTEM, nil
case LEVELPROJECT:
if p.Namespace == "*" {
return SCOPEALLPROJECT, nil
}
pro, err := d.proMgr.Get(ctx, p.Namespace)
if err != nil {
return "", err
}
return fmt.Sprintf("/project/%d", pro.ProjectID), nil
}
return "", errors.New(nil).WithMessage("unknown robot kind").WithCode(errors.BadRequestCode)
}
// set the project info if it's a project level robot
func SetProject(ctx context.Context, r *Robot) error {
if r == nil {View on GitHub (pinned to 7b2fd08cc5)
Solutions
- For system-wide scope set kind=system with namespace="/"
- For project scope set kind=project with namespace=<project_name> or '*' for all projects
- Validate the (kind, namespace) pairs in your client before submitting
Example fix
// before
{"permissions": [{"kind": "system", "namespace": "myproject", "access": [...]}]} // 400
// after
{"permissions": [{"kind": "project", "namespace": "myproject", "access": [...]}]}
// or system-wide:
{"permissions": [{"kind": "system", "namespace": "/", "access": [...]}]} Defensive patterns
Strategy: validation
Validate before calling
func validatePermission(p Permission) error {
switch p.Kind {
case "system":
if p.Namespace != "/" { return errors.New("system scope requires namespace '/'") }
case "project":
if p.Namespace != "*" && !validProjectName(p.Namespace) { return errors.New("invalid project namespace") }
default:
return errors.New("unknown permission kind")
}
return nil
} Type guard
func isUnknownNamespaceErr(err error) bool {
return errors.IsErr(err, errors.BadRequestCode) &&
strings.Contains(err.Error(), "unknown namespace")
} Try / catch
if _, err := robotCtl.CreateRobot(...); err != nil {
if errors.IsErr(err, errors.BadRequestCode) && strings.Contains(err.Error(), "unknown namespace") {
// fix (kind, namespace) pair: system=>'/', project=>name|'*'
}
} Prevention
- Treat (kind=system, namespace='/') as the only system-scope shape
- Use kind=project with the project name or '*' for project scopes
- Validate permission arrays in client code before POST /robots
When it happens
Trigger: POST /api/v2.0/robots (or PUT /robots/{id}) with a permissions entry like {"kind": "system", "namespace": ""}, {"kind": "system", "namespace": "library"}, or {"kind": "system", "namespace": "*"}.
Common situations: Reusing a project-level permission template for system scope; omitting namespace and expecting a default; copying permission JSON from docs where '/' was lost by URL normalization.
Related errors
- File {} not exist
- Internal dir for tls {} not exist
- Port number in metrics is not valid
- Jaeger Colector Endpoint or Agent host not set, must set one
- Jaeger Colector Endpoint and Agent host both set, only can s
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/fd9405c5eef0bbdd.
Report an issue: GitHub.