{"record":{"id":"d0f0532fffc4ecd8","repo":"goharbor/harbor","slug":"the-system-is-in-read-only-mode-cancel-the-reques","errorCode":null,"errorMessage":"the system is in read only mode, cancel the request","messagePattern":"the system is in read only mode, cancel the request","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/pkg/registry/interceptor/readonly/interceptor.go","lineNumber":31,"sourceCode":"// limitations under the License.\n\npackage readonly\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/goharbor/harbor/src/lib/cache\"\n\t\"github.com/goharbor/harbor/src/lib/cache/memory\"\n\t\"github.com/goharbor/harbor/src/lib/config\"\n\titcp \"github.com/goharbor/harbor/src/pkg/registry/interceptor\"\n)\n\n// Err indicates the system is in read only mode\nvar (\n\tErr = errors.New(\"the system is in read only mode, cancel the request\")\n\tkey = \"read-only\"\n)\n\n// NewInterceptor creates an interceptor that intercepts any requests if the system is set to read-only\nfunc NewInterceptor() itcp.Interceptor {\n\t// ignore the error as the New return nil error\n\tcache, _ := memory.New(cache.Options{\n\t\tExpiration: 5 * time.Second,\n\t\tCodec:      cache.DefaultCodec(),\n\t})\n\treturn &interceptor{cache: cache}\n}\n\ntype interceptor struct {\n\tcache cache.Cache\n}\n\nfunc (i *interceptor) Intercept(req *http.Request) error {","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/goharbor/harbor/blob/7b2fd08cc568955cca339afeefab27372840d936/src/pkg/registry/interceptor/readonly/interceptor.go#L13-L49","documentation":"Sentinel error returned by the read-only interceptor when Harbor is configured in read-only mode. NewInterceptor wraps requests with a short-TTL (5s) in-memory cache of the read-only config flag; when the flag is set, mutating requests are intercepted and cancelled with this error. It is a deliberate system-state rejection, not a bug.","triggerScenarios":"Any write-style API call (push, tag deletion, config change, project create) routed through the registry proxy while the read-only setting is enabled in Harbor's configuration; also triggered automatically when Harbor switches itself to read-only, e.g. during failed free-space checks or database maintenance windows.","commonSituations":"Harbor entered read-only mode because the registry storage filled up past the threshold; an admin enabled read-only for maintenance/upgrade; jobs (GC, replication, scanning) retrying writes during the window; users pushing images during migration.","solutions":["Wait for the maintenance window to end, then retry the operation; the interceptor cache expires in 5 seconds so the system recovers as soon as the flag is cleared","Check and clear the read-only setting via Harbor configuration (project config / system settings) if it was left on accidentally","If storage-full caused it, free registry storage or raise the threshold before clearing the flag","Ensure background jobs (replication, scan) are paused or tolerate deferral while read-only is on"],"exampleFix":"// before\nif err := deleteTag(tag); err != nil {\n    return err // surfaces during read-only window\n}\n\n// after\nmaxAttempts := 10\nfor i := 0; i < maxAttempts; i++ {\n    err := deleteTag(tag)\n    if err == nil || !errors.Is(err, readonly.Err) {\n        break\n    }\n    time.Sleep(30 * time.Second) // retry after read-only is lifted\n}","handlingStrategy":"retry","validationCode":"// Check read-only state before issuing writes (mirror of interceptor cache)\nif config.ReadOnly() {\n    return readonly.Err\n}","typeGuard":null,"tryCatchPattern":"if err := op(); err != nil && errors.Is(err, readonly.Err) {\n    // schedule retry with backoff; system is read-only for a bounded window\n    time.AfterFunc(time.Minute, func() { _ = op() })\n}","preventionTips":["Surface a user-facing banner when the system is read-only so clients stop writing","Pause replication/scan jobs during maintenance windows","Monitor registry storage free space to avoid automatic read-only activation"],"tags":["read-only","interceptor","maintenance","system-state"],"backgroundTag":null,"analyzedSha":"7b2fd08cc568955cca339afeefab27372840d936","analyzedAt":"2026-08-16T00:00:10.961Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}