dapr/dapr · error

unknown status returned from app while processing pub/sub ev

Error message

unknown status returned from app while processing pub/sub event %v, status: %v, err: %w

What it means

The streaming subscriber's processed response carried a TopicEventResponse status other than SUCCESS, RETRY, or DROP, so daprd treats it as retriable. As with the other unknown-status errors, unset defaults to SUCCESS (0); this fires only on an enum value the running daprd build does not recognize — typically SDK/proto version skew on the alpha streaming API.

Source

Thrown at pkg/runtime/subscription/postman/streaming/streaming.go:80

	switch resp.GetStatus().GetStatus() {
	case rtv1pb.TopicEventResponse_SUCCESS: //nolint:nosnakecase
		// on uninitialized status, this is the case it defaults to as an uninitialized status defaults to 0 which is
		// success from protobuf definition
		diag.DefaultComponentMonitoring.PubsubIngressEvent(ctx, msg.PubSub, strings.ToLower(string(contribpubsub.Success)), "", msg.Topic, elapsed)
		return nil
	case rtv1pb.TopicEventResponse_RETRY: //nolint:nosnakecase
		diag.DefaultComponentMonitoring.PubsubIngressEvent(ctx, msg.PubSub, strings.ToLower(string(contribpubsub.Retry)), "", msg.Topic, elapsed)
		// TODO: add retry error info
		return fmt.Errorf("RETRY status returned from app while processing pub/sub event %v: %w", msg.CloudEvent[contribpubsub.IDField], rterrors.NewRetriable(nil))
	case rtv1pb.TopicEventResponse_DROP: //nolint:nosnakecase
		log.Warnf("DROP status returned from app while processing pub/sub event %v", msg.CloudEvent[contribpubsub.IDField])
		diag.DefaultComponentMonitoring.PubsubIngressEvent(ctx, msg.PubSub, strings.ToLower(string(contribpubsub.Drop)), "", msg.Topic, elapsed)

		return pubsub.ErrMessageDropped
	default:
		// Consider unknown status field as error and retry
		diag.DefaultComponentMonitoring.PubsubIngressEvent(ctx, msg.PubSub, strings.ToLower(string(contribpubsub.Retry)), "", msg.Topic, elapsed)
		return fmt.Errorf("unknown status returned from app while processing pub/sub event %v, status: %v, err: %w", msg.CloudEvent[contribpubsub.IDField], resp.GetStatus(), rterrors.NewRetriable(nil))
	}
}

func (s *streaming) DeliverBulk(context.Context, *postman.DeliverBulkRequest) error {
	return errors.New("not implemented")
}

View on GitHub (pinned to 74ad417027)

Solutions

  1. Align SDK and daprd versions (streaming subscribe is alpha and changes between releases); redeploy together
  2. In custom stream handlers, respond with SUCCESS/RETRY/DROP only, or omit the status for success
  3. Add deadLetterTopic plus bounded retries so unrecognized statuses terminate in DLQ

Example fix

// before
await stream.Send(&rtv1.SubscribeTopicEventsRequestProcessedAlpha1{
	Id: id, Status: &rtv1.TopicEventResponse{Status: rtv1.TopicEventResponse(7)},
})

// after
await stream.Send(&rtv1.SubscribeTopicEventsRequestProcessedAlpha1{
	Id: id, Status: &rtv1.TopicEventResponse{Status: rtv1.TopicEventResponse_SUCCESS},
})
Defensive patterns

Strategy: type-guard

Validate before calling

// Normalize the status before writing the processed message to the stream.
if !isValidTopicEventStatus(s) {
	s = rtv1.TopicEventResponse_SUCCESS
}

Type guard

func isValidTopicEventStatus(s rtv1.TopicEventResponse_Status) bool {
	switch s {
	case rtv1.TopicEventResponse_SUCCESS, rtv1.TopicEventResponse_RETRY, rtv1.TopicEventResponse_DROP:
		return true
	}
	return false
}

Prevention

When it happens

Trigger: Streaming subscriber built against a different dapr proto revision sends a status outside {0,1,2}; custom stream handler assigns a raw enum int; mixed daprd/SDK versions during rollout of the alpha API.

Common situations: Early-adopter mismatch between SDK and sidecar on SubscribeTopicEventsAlpha1; hand-implemented streaming clients; proto regenerated from a newer dapr/dapr checkout.

Related errors


AI-assisted analysis of dapr/dapr@74ad417027 (2026-08-16). Data as JSON: /api/errors/a4255fa7276036a3. Report an issue: GitHub.