goharbor/harbor · error · lib/errors.Error
NOT_FOUND
NOT_FOUND
Error message
replication execution %d not found
What it means
Returned by the replication controller's GetExecution (src/controller/replication/execution.go:242) when listing executions by ID and VendorType=REPLICATION returns zero rows. The vendor-type filter means an execution ID belonging to another job type (e.g. garbage collection, scan) will also report not found. Maps to HTTP 404.
Source
Thrown at src/controller/replication/execution.go:242
if value, exist := query.Keywords["policy_id"]; exist {
query.Keywords["VendorID"] = value
delete(query.Keywords, "policy_id")
}
return query
}
func (c *controller) GetExecution(ctx context.Context, id int64) (*Execution, error) {
execs, err := c.execMgr.List(ctx, &q.Query{
Keywords: map[string]any{
"ID": id,
"VendorType": job.ReplicationVendorType,
},
})
if err != nil {
return nil, err
}
if len(execs) == 0 {
return nil, errors.New(nil).WithCode(errors.NotFoundCode).
WithMessagef("replication execution %d not found", id)
}
return convertExecution(execs[0]), nil
}
func (c *controller) TaskCount(ctx context.Context, query *q.Query) (int64, error) {
query = q.MustClone(query)
query.Keywords["VendorType"] = job.ReplicationVendorType
return c.taskMgr.Count(ctx, query)
}
func (c *controller) ListTasks(ctx context.Context, query *q.Query) ([]*Task, error) {
query = q.MustClone(query)
query.Keywords["VendorType"] = job.ReplicationVendorType
tks, err := c.taskMgr.List(ctx, query)
if err != nil {
return nil, err
}View on GitHub (pinned to 7b2fd08cc5)
Solutions
- Verify the ID by listing executions first: GET /api/v2.0/replication/executions and match the ID
- Confirm you queried the right resource type (execution vs task) and the right API (replication vs webhook executions)
- Treat 404 as terminal for retry loops - do not keep retrying a deleted execution
Example fix
// before
exec, err := replicationCtl.GetExecution(ctx, 999999)
// 404: replication execution 999999 not found
// after
execs, err := apiClient.ListReplicationExecutions(nil)
if idExists(execs, 999999) {
exec, err = apiClient.GetReplicationExecution(999999)
} Defensive patterns
Strategy: validation
Validate before calling
execs, err := apiClient.ListReplicationExecutions(&q.Query{Keywords: map[string]any{"PolicyID": policyID}})
if err != nil { return err }
found := false
for _, e := range execs {
if e.ID == wantID { found = true; break }
}
if !found { return fmt.Errorf("execution %d not in replication list", wantID) } Type guard
func isExecutionNotFound(err error) bool {
return errors.IsNotFoundErr(err) || errors.IsErr(err, errors.NotFoundCode)
} Try / catch
exec, err := replicationCtl.GetExecution(ctx, id)
if err != nil {
if errors.IsNotFoundErr(err) {
// remove from UI cache; do not retry
}
return err
} Prevention
- Always obtain execution IDs from the list endpoint, never from stale logs
- Guard id-driven lookups with an existence check when IDs cross service boundaries
- Treat 404 as terminal in retry loops
When it happens
Trigger: GET /api/v2.0/replication/executions/{id} with an ID that does not exist, belongs to a non-replication vendor type, or was purged; calling controller.GetExecution(ctx, id) after the execution record was cleaned up.
Common situations: Stale execution ID held in a dashboard or script; paging through executions while GC deletes old records; passing a task ID where an execution ID was expected; typo'd or truncated ID from logs.
Related errors
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/8238f7a4d0587e58.
Report an issue: GitHub.