{"record":{"id":"205472581e8a5ca7","repo":"containerd/containerd","slug":"commit-failed-w","errorCode":null,"errorMessage":"commit failed: %w","messagePattern":"commit failed: %w","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/content/proxy/content_writer.go","lineNumber":130,"sourceCode":"\t\t\terr = err1\n\t\t}\n\t}()\n\n\tvar base content.Info\n\tfor _, opt := range opts {\n\t\tif err := opt(&base); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\tresp, err := rw.send(&contentapi.WriteContentRequest{\n\t\tAction:   contentapi.WriteAction_COMMIT,\n\t\tTotal:    size,\n\t\tOffset:   rw.offset,\n\t\tExpected: expected.String(),\n\t\tLabels:   base.Labels,\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"commit failed: %w\", errgrpc.ToNative(err))\n\t}\n\n\tif size != 0 && resp.Offset != size {\n\t\treturn fmt.Errorf(\"unexpected size: %v != %v\", resp.Offset, size)\n\t}\n\n\tactual := digest.Digest(resp.Digest)\n\tif expected != \"\" && actual != expected {\n\t\treturn fmt.Errorf(\"unexpected digest: %v != %v\", resp.Digest, expected)\n\t}\n\n\trw.digest = actual\n\trw.offset = resp.Offset\n\treturn nil\n}\n\nfunc (rw *remoteWriter) Truncate(size int64) error {\n\t// This truncation won't actually be validated until a write is issued.","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/containerd/containerd/blob/4246446a2bf7d03837b0244118d858799393bd80/core/content/proxy/content_writer.go#L112-L148","documentation":"remoteWriter.Commit sends a WriteAction_COMMIT request through the content proxy. Transport-level failures of that RPC are converted to native errors and wrapped as 'commit failed'. This happens after the data has been written, when finalizing the blob ingest on the remote side.","triggerScenarios":"Calling Commit on a proxied content writer when the commit RPC fails — daemon shutdown between write and commit, context timeout, ingest expired/collected remotely, or the ref was already committed by another process.","commonSituations":"Push finalized after the containerd daemon restarted; slow networks causing context deadline during commit; concurrent writers using the same ingest ref; expected digest mismatches reported by the remote as RPC errors.","solutions":["Read the wrapped gRPC/ttrpc error code to distinguish transient (Unavailable, DeadlineExceeded) from permanent failures","Retry the commit; if the ingest was lost, recreate the writer, rewrite data, and commit again","Check that the expected digest and size match the actual content to avoid remote-side validation failures","Increase context timeout for large blobs so commit is not cut off"],"exampleFix":"// before: short-lived ctx\nerr := rw.Commit(ctx, size, expectedDigest)\n// after: dedicated timeout + one retry\nctx2, cancel := context.WithTimeout(context.Background(), 5*time.Minute)\ndefer cancel()\nif err := rw.Commit(ctx2, size, expectedDigest); err != nil {\n    if status.Code(err) == codes.Unavailable {\n        return rw.Commit(ctx2, size, expectedDigest)\n    }\n    return err\n}","handlingStrategy":"retry","validationCode":"st, err := rw.Status()\nif err != nil { return err }\nif size != 0 && st.Offset != size {\n    return fmt.Errorf(\"aborting commit: written %d of %d\", st.Offset, size)\n}","typeGuard":null,"tryCatchPattern":"err := rw.Commit(ctx, size, expected)\nif err != nil {\n    if status.Code(err) == codes.Unavailable || status.Code(err) == codes.DeadlineExceeded {\n        ctx2, cancel := context.WithTimeout(context.Background(), commitTimeout)\n        defer cancel()\n        err = rw.Commit(ctx2, size, expected)\n    }\n}\nreturn err","preventionTips":["Use a fresh, long-lived context for commit","Commit exactly once per writer; concurrent commits cause RPC conflicts","Handle ErrAlreadyExists from duplicate commits as success when content matches"],"tags":["grpc","ttrpc","content-writer","commit","rpc-error"],"backgroundTag":"commit-failed","analyzedSha":"4246446a2bf7d03837b0244118d858799393bd80","analyzedAt":"2026-09-02T00:14:43.053Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}