Relay
1.x
Docs/Relay/Error Handling
Open

Reading2 min
Updated31 Jul 2026
Sourcev1/concepts/errors.mdx

Relay defines a set of sentinel errors in the root package. Use errors.Is to check for specific conditions.

Sentinel errors01

var (
    ErrNoStore                 = errors.New("relay: store is required")
    ErrEndpointNotFound        = errors.New("relay: endpoint not found")
    ErrEventTypeNotFound       = errors.New("relay: event type not found")
    ErrEventTypeDeprecated     = errors.New("relay: event type is deprecated")
    ErrPayloadValidationFailed = errors.New("relay: payload validation failed")
    ErrDuplicateIdempotencyKey = errors.New("relay: duplicate idempotency key")
    ErrEndpointDisabled        = errors.New("relay: endpoint is disabled")
    ErrStoreClosed             = errors.New("relay: store is closed")
    ErrMigrationFailed         = errors.New("relay: migration failed")
    ErrDLQNotFound             = errors.New("relay: dlq entry not found")
    ErrDeliveryNotFound        = errors.New("relay: delivery not found")
    ErrEventNotFound           = errors.New("relay: event not found")
)

Checking errors02

err := r.Send(ctx, evt)
if errors.Is(err, relay.ErrEventTypeNotFound) {
    // event type not registered in the catalog
}

Wrapping convention03

Subsystems wrap the sentinel with fmt.Errorf and %w:

return fmt.Errorf("%w: %s", ErrEventTypeNotFound, evt.Type)

Validation errors04

The endpoint service returns *endpoint.ValidationError for invalid input:

var valErr *endpoint.ValidationError
if errors.As(err, &valErr) {
    log.Printf("invalid %s: %s", valErr.Field, valErr.Message)
}

Idempotency05

Duplicate idempotency keys are not treated as errors. When Send() encounters a duplicate, it returns nil (no-op success).