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

  1. For system-wide scope set kind=system with namespace="/"
  2. For project scope set kind=project with namespace=<project_name> or '*' for all projects
  3. 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

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


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