{"record":{"id":"cf781ce0bc64ac4b","repo":"containerd/containerd","slug":"subscription-error-w","errorCode":null,"errorMessage":"subscription error: %w","messagePattern":"subscription error: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"plugins/services/events/service.go","lineNumber":114,"sourceCode":"\t}\n\n\treturn empty, nil\n}\n\nfunc (s *service) Subscribe(req *api.SubscribeRequest, srv api.Events_SubscribeServer) error {\n\tctx, cancel := context.WithCancel(srv.Context())\n\tdefer cancel()\n\n\teventq, errq := s.events.Subscribe(ctx, req.Filters...)\n\tfor {\n\t\tselect {\n\t\tcase ev := <-eventq:\n\t\t\tif err := srv.Send(toProto(ev)); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed sending event to subscriber: %w\", err)\n\t\t\t}\n\t\tcase err := <-errq:\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"subscription error: %w\", err)\n\t\t\t}\n\n\t\t\treturn nil\n\t\t}\n\t}\n}\n\nfunc toProto(env *events.Envelope) *types.Envelope {\n\treturn &types.Envelope{\n\t\tTimestamp: protobuf.ToTimestamp(env.Timestamp),\n\t\tNamespace: env.Namespace,\n\t\tTopic:     env.Topic,\n\t\tEvent:     typeurl.MarshalProto(env.Event),\n\t}\n}\n\nfunc fromProto(env *types.Envelope) *events.Envelope {\n\treturn &events.Envelope{","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/containerd/containerd/blob/4246446a2bf7d03837b0244118d858799393bd80/plugins/services/events/service.go#L96-L132","documentation":"The events service Subscribe loop received a non-nil error on the broker's error queue (errq) and returns it wrapped as 'subscription error'. It indicates the underlying event broker subscription terminated abnormally, not a client transport problem.","triggerScenarios":"The event exchange closes the subscriber's error channel with an error, typically because the subscription's context was canceled or the broker was shut down while the stream was active.","commonSituations":"containerd daemon shutting down while clients hold event subscriptions; the Subscribe context (client disconnect) canceled the broker subscription; internal broker misuse.","solutions":["Re-subscribe after the daemon/subscription is restored","Check daemon logs for broker shutdown or restart at the same time","Ensure clients reconnect with backoff on subscription loss","If persistent, verify the event exchange plugin is healthy and enabled"],"exampleFix":"// before: single subscribe, give up on error\n// after: client-side retry loop\nfor {\n    err := subscribeEvents(ctx, client)\n    if ctx.Err() != nil { return }\n    time.Sleep(time.Second)\n}","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"err := subscribe(ctx)\nif err != nil && strings.Contains(err.Error(), \"subscription error\") {\n    select {\n    case <-time.After(backoff):\n    case <-ctx.Done():\n        return ctx.Err()\n    }\n    return subscribe(ctx) // re-subscribe\n}","preventionTips":["Implement client re-subscribe loops around event consumption","Monitor daemon restarts; treat subscription errors during shutdown as expected","Pin event exchange plugin as enabled in config"],"tags":["events","subscription","containerd"],"backgroundTag":"event-subscription-error","analyzedSha":"4246446a2bf7d03837b0244118d858799393bd80","analyzedAt":"2026-09-02T00:14:43.053Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}