dapr/dapr · error

ERR_PUBLISH_OUTBOX

ERR_PUBLISH_OUTBOX

Error message

error publishing internal outbox message: could not find outbox configuration on state store %s

What it means

Outbox error (code ERR_PUBLISH_OUTBOX): PublishInternal was invoked for a state store that has no entry in outboxStores. Entries are only created by AddOrUpdateOutbox when the state store component declares both 'outboxPublishPubsub' and 'outboxPublishTopic' metadata (pkg/runtime/pubsub/outbox.go:102-135). The transactional state save therefore cannot be forwarded to the outbox topic.

Source

Thrown at pkg/runtime/pubsub/outbox.go:167

	uid, err := uuid.NewRandom()
	if err != nil {
		return nil, err
	}

	return state.SetRequest{
		Key:   outboxStatePrefix + "-" + uid.String(),
		Value: "0",
	}, nil
}

// PublishInternal publishes the state to an internal topic for outbox processing and returns the updated list of transactions
func (o *outboxImpl) PublishInternal(ctx context.Context, stateStore string, operations []state.TransactionalStateOperation, source, traceID, traceState string) ([]state.TransactionalStateOperation, error) {
	o.lock.RLock()
	c, ok := o.outboxStores[stateStore]
	o.lock.RUnlock()

	if !ok {
		return nil, fmt.Errorf("error publishing internal outbox message: could not find outbox configuration on state store %s", stateStore)
	}

	projections := map[string]state.SetRequest{}

	for i, op := range operations {
		sr, ok := op.(state.SetRequest)

		if ok {
			for k, v := range sr.Metadata {
				if k == "outbox.projection" && kitstrings.IsTruthy(v) {
					projections[sr.Key] = sr

					operations = append(operations[:i], operations[i+1:]...)
				}
			}
		}
	}

View on GitHub (pinned to 74ad417027)

Solutions

  1. Add both metadata entries to the state store component: outboxPublishPubsub (and optionally outboxPubsub, outboxDiscardWhenMissingState) plus outboxPublishTopic
  2. Check exact spelling/case of the metadata keys - 'outboxPublishPubsub', 'outboxPublishTopic'
  3. Ensure the named state store has initialized successfully (a failed init can skip outbox registration)
  4. Retry the transaction after re-applying the corrected component

Example fix

# before (state store without outbox metadata)
spec:
  type: state.postgres
  version: v1
  metadata: []
# after
spec:
  type: state.postgres
  version: v1
  metadata:
    - name: outboxPublishPubsub
      value: redis-pubsub
    - name: outboxPublishTopic
      value: outbox-events
Defensive patterns

Strategy: validation

Validate before calling

// Check outbox enablement before sending a transactional save with outbox metadata
if !outbox.Enabled(stateStoreName) {
    return fmt.Errorf("state store %s lacks outboxPublishPubsub/outboxPublishTopic metadata", stateStoreName)
}

Type guard

func outboxConfigured(storeName string, stores map[string]struct{}) bool {
    _, ok := stores[storeName]
    return ok
}

Try / catch

On ERR_PUBLISH_OUTBOX, fail the state transaction explicitly - do not retry with the same metadata. Surface to the operator that the state store component is missing outbox configuration, fix the manifest, then re-issue the transaction.

Prevention

When it happens

Trigger: Saving state transactionally with outbox metadata naming a state store whose component YAML lacks outboxPublishPubsub/outboxPublishTopic; a typo in those metadata keys (they are case-sensitive); publishing before the state store component finished processing; deleting and re-adding the store without the outbox metadata.

Common situations: App sets 'outbox.' metadata on a /state/transaction request assuming outbox is enabled globally; enabling outbox on the pubsub side only; renaming the state store without updating the app's metadata; hot reload dropping the metadata.

Related errors


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