goharbor/harbor · error · lib/errors.Error
PRECONDITION
PRECONDITION
Error message
the policy %d is disabled
What it means
Thrown by the replication controller's Start() (src/controller/replication/execution.go:104) when a replication execution is requested for a policy whose Enabled flag is false. It is returned before any execution record or task is created. The PRECONDITION code maps to HTTP 412, telling the caller the policy must be enabled before it can run.
Source
Thrown at src/controller/replication/execution.go:104
wp: lib.NewWorkerPool(10),
}
}
type controller struct {
repMgr replication.Manager
execMgr task.ExecutionManager
taskMgr task.Manager
regMgr reg.Manager
scheduler scheduler.Scheduler
flowCtl flow.Controller
ormCreator orm.Creator
wp *lib.WorkerPool
}
func (c *controller) Start(ctx context.Context, policy *replicationmodel.Policy, resource *model.Resource, trigger string) (int64, error) {
logger := log.GetLogger(ctx)
if !policy.Enabled {
return 0, errors.New(nil).WithCode(errors.PreconditionCode).
WithMessagef("the policy %d is disabled", policy.ID)
}
// create an execution record
extra := make(map[string]any)
if op := operator.FromContext(ctx); op != "" {
extra["operator"] = op
}
var count int64
// If running executions are found, skip the current execution and mark it as error.
if policy.SingleActiveReplication {
var err error
count, err = c.execMgr.Count(ctx, &q.Query{
Keywords: map[string]any{
"VendorType": job.ReplicationVendorType,
"VendorID": policy.ID,
"Status": job.RunningStatus.String(),
},View on GitHub (pinned to 7b2fd08cc5)
Solutions
- Enable the policy first: PUT /api/v2.0/replication/policies/{id} with {"enabled": true}, then retry the execution request
- Fetch the policy immediately before starting and verify enabled=true, or re-fetch on 412 and retry once
- Fix automation scripts that hard-code policy IDs of policies that were later disabled
Example fix
// before
POST /api/v2.0/replication/executions
{"policy_id": 7} // 412: the policy 7 is disabled
// after
PUT /api/v2.0/replication/policies/7
{"enabled": true}
POST /api/v2.0/replication/executions
{"policy_id": 7} Defensive patterns
Strategy: validation
Validate before calling
policy, err := apiClient.GetReplicationPolicy(policyID)
if err != nil {
return err
}
if !policy.Enabled {
// enable first: PUT /replication/policies/%d with {"enabled": true}
return fmt.Errorf("policy %d disabled; enable before starting", policyID)
}
return apiClient.StartReplication(policyID) Type guard
func isPolicyDisabledErr(err error) bool {
return errors.IsErr(err, errors.PreconditionCode) &&
strings.Contains(err.Error(), "is disabled")
} Try / catch
if _, err := replicationCtl.Start(ctx, policy, res, trigger); err != nil {
if errors.IsErr(err, errors.PreconditionCode) && strings.Contains(err.Error(), "is disabled") {
// enable policy, retry once
}
return err
} Prevention
- Always GET the policy and check .Enabled immediately before triggering an execution
- Give automation a re-fetch-and-retry-once path for 412 responses
- Alert when a replication policy is disabled so triggers do not fail silently
When it happens
Trigger: POST /api/v2.0/replication/executions with {"policy_id": N} where policy N has enabled=false; or calling replication.Controller.Start(ctx, policy, ...) with a policy fetched before another admin disabled it.
Common situations: Triggering a replication manually from automation/CI that assumes the policy is active; a policy disabled by a retention/cleanup script or another administrator; UI user clicking 'Replicate' on a stopped policy; race where the policy was disabled between fetch and start.
Related errors
AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16).
Data as JSON: /api/errors/72130ecc327f7ef4.
Report an issue: GitHub.