goharbor/harbor · error
the namespace of resource cannot be null
Error message
the namespace of resource cannot be null
What it means
Returned by the Quay adapter's PrepareForPush (src/pkg/reg/adapter/quay/adapter.go:161) when resource.Metadata is set but resource.Metadata.Repository is nil. The adapter needs Repository.Name to compute the Quay namespace (first path segment) to auto-create; a nil Repository pointer makes that impossible, so it fails before any API call to Quay.
Source
Thrown at src/pkg/reg/adapter/quay/adapter.go:161
}, nil
}
// PrepareForPush does the prepare work that needed for pushing/uploading the resource
// eg: create the namespace or repository
func (a *adapter) PrepareForPush(resources []*model.Resource) error {
if !a.autoCreateNs {
return nil
}
namespaces := []string{}
for _, resource := range resources {
if resource == nil {
return errors.New("the resource cannot be null")
}
if resource.Metadata == nil {
return errors.New("the metadata of resource cannot be null")
}
if resource.Metadata.Repository == nil {
return errors.New("the namespace of resource cannot be null")
}
if len(resource.Metadata.Repository.Name) == 0 {
return errors.New("the name of the namespace cannot be null")
}
paths := strings.Split(resource.Metadata.Repository.Name, "/")
namespace := paths[0]
namespaces = append(namespaces, namespace)
}
for _, namespace := range namespaces {
err := a.createNamespace(&model.Namespace{
Name: namespace,
})
if err != nil {
return fmt.Errorf("create namespace '%s' in Quay error: %v", namespace, err)
}
log.Debugf("namespace %s created", namespace)
}View on GitHub (pinned to 7b2fd08cc5)
Solutions
- Always set Metadata.Repository (with a non-empty Name) for resources destined for push.
- Validate the slice up front (see validationCode) for a precise index.
- Assert non-nil Repository in builder unit tests.
- When cloning source metadata, copy the Repository pointer rather than rebuilding it field-by-field.
Example fix
// before
Metadata: &model.ResourceMetadata{Vtags: []string{"latest"}},
// after
Metadata: &model.ResourceMetadata{
Repository: &model.Repository{Name: "myteam/ubuntu"},
Vtags: []string{"latest"},
}, Defensive patterns
Strategy: validation
Validate before calling
for i, r := range resources {
if r == nil || r.Metadata == nil || r.Metadata.Repository == nil {
return fmt.Errorf("resources[%d]: missing resource/metadata/repository", i)
}
} Type guard
func hasRepository(r *model.Resource) bool {
return r != nil && r.Metadata != nil && r.Metadata.Repository != nil
} Try / catch
if err := a.PrepareForPush(resources); err != nil {
if strings.Contains(err.Error(), "namespace of resource cannot be null") {
// set Metadata.Repository before retry
}
return err
} Prevention
- Copy the source Metadata (including Repository pointer) when cloning.
- Builder tests assert Repository non-nil.
When it happens
Trigger: Passing a resource whose ResourceMetadata has Vtags/Artifact but no Repository to quay PrepareForPush with autoCreateNs enabled.
Common situations: Metadata built for tag operations reused for push; struct literals after a refactor that moved Repository into a conditional branch; clones that copy only selected fields.
Related errors
- the resource cannot be null
- the metadata of resource cannot be null
- the name of the repository cannot be null
- the resource cannot be null
- the metadata of resource cannot be null
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/82ed0bf990e30caa.
Report an issue: GitHub.