Service Bus Message Error Classification Strategy
Spike: Error Classification Design (User Story 762531)
1. Summary
This document defines a standardized error classification strategy for Azure Service Bus message processing across Fluxx microservices. The strategy distinguishes between transient failures (temporary, retriable) and permanent failures (non-retriable) to optimize system reliability and operational efficiency.
Key Outcomes
- Clear taxonomy of message processing errors
- Decision rules for retry vs dead-letter actions
- Improved system reliability and reduced operational noise
- Ensure the approach is consistent, configurable, observable, debuggable, and testable.
2. Problem Statement
Current State
Currently in fluxx-extractor (and likely other services):
- All message processing errors are treated the same way
- Failed messages are always abandoned for retry, regardless of error type
- No distinction between transient (network timeout) vs permanent (invalid data) failures
- Validation errors retry indefinitely until max delivery count
- Dead-letter queues contain mix of retriable and non-retriable messages
- Limited error metadata makes troubleshooting difficult
Impact
- Wasted Service Bus resources on non-retriable errors
- Delayed identification of systematic issues (e.g., missing configuration)
- Poor operational visibility into failure reasons
- Inconsistent behavior across microservices
Design Goals
Primary Goals
- Clear Error Taxonomy - Establish standardized categories for all message processing failures
- Intelligent Retry Logic - Apply conditional retry based on error classification
- Operational Correctness - Dead-letter permanent failures immediately, retry transient failures
- Cross-Service Consistency - Same approach in all Fluxx microservices
- Enhanced Observability - Rich metadata and structured logging for debugging
3. Error Classification Framework
3.1 Classification Principles
Transient Errors
Errors that are temporary and likely to succeed on retry without any code or data changes.
Characteristics:
- External dependency temporarily unavailable
- Network connectivity issues
- Resource contention that resolves over time
- Rate limiting that expires
Strategy: Retry with exponential backoff
Permanent Errors
Errors that will never succeed regardless of retries without intervention.
Characteristics:
- Invalid input data
- Missing configuration
- Business rule violations
- Resources that don’t exist
Strategy: Immediate dead-letter for manual investigation
4. Error Taxonomy
4.1 Transient Error Categories
TRANSIENT_SERVICE
External service temporarily unavailable
Rationale: Services typically recover within minutes. Retry allows automatic recovery without manual intervention.
TRANSIENT_NETWORK
Network connectivity issues
Rationale: Network issues are often transient. DNS, routing, and firewall issues typically resolve quickly.
TRANSIENT_THROTTLING
Rate limiting by external service
Rationale: Rate limits typically reset automatically. Respecting Retry-After prevents additional throttling.
Future Enhancement: Implement exponential backoff or circuit breaker pattern.
TRANSIENT_RESOURCE
Resource contention that resolves over time
Rationale: Resource contention is temporary by nature. Deadlocks resolve automatically, and pools refill.
4.2 Permanent Error Categories
PERMANENT_VALIDATION
Invalid message data or structure
Rationale: Invalid data will never become valid through retry. Immediate dead-lettering allows quick identification and fix.
Dead-Letter Metadata:
PERMANENT_CONFIGURATION
Missing or invalid configuration
Rationale: Configuration issues require deployment or database changes. Retry wastes resources and delays detection.
Operational Response:
- Alert: Page on-call immediately (high severity)
- Investigate: Check configuration in database/environment
- Fix: Add missing configuration
- Reprocess: Resubmit dead-lettered messages
PERMANENT_NOT_FOUND
Resource doesn’t exist
Rationale: Resources don’t spontaneously appear. Retry wastes resources checking for non-existent entities.
Decision Tree:
PERMANENT_AUTHORIZATION
Authentication or permission failure
Rationale: Credentials don’t fix themselves. Immediate dead-lettering highlights security/access issues.
Security Consideration: Don’t log credentials in error metadata.
PERMANENT_BUSINESS_RULE
Business logic prevents processing
Rationale: Business rules are deterministic. Retry won’t change the outcome without state changes.
PERMANENT_MALFORMED
Message structure invalid
Rationale: Malformed messages indicate producer bugs. Retry wastes lock time on unparseable data.
5. HTTP Status Code Mapping
5.1 Complete Status Code Classification
5.2 Edge Cases
408 Request Timeout
Classification: TRANSIENT_TIMEOUT Retryable
Rationale: Despite being 4xx, this indicates network/server performance issue rather than client error.
429 Too Many Requests
Classification: TRANSIENT_THROTTLING Retryable
Special Handling: Check for Retry-After header and respect the delay.
409 Conflict
Classification: PERMANENT_BUSINESS_RULE Not retryable
Rationale: Conflicts require state changes or business logic investigation. Automatic retry won’t resolve.
6. Network Error Code Mapping
6.1 Node.js Error Codes
Note: All network errors are considered transient unless they persist beyond max retries.
7. Database Error Classification
7.1 SQL Error Patterns
8. Service Bus Error Classification
8.1 Service Bus Specific Errors
9. Decision Matrix
9.1 Retry Decision Table
This comprehensive table shows exactly how the system decides whether to retry or dead-letter a message based on error characteristics.
9.2 Quick Reference Decision Tree
Use PERMANENT errors when retry will NEVER succeed
without manual intervention (code, config, or data change)
PERMANENT_VALIDATION
-
Missing required fields
-
Invalid data format (email, date, etc.)
-
Wrong data type (string vs number)
-
Value out of acceptable range
-
Schema validation failure
-
HTTP: 400 (Bad Request), 422 (Unprocessable Entity)
PERMANENT_CONFIGURATION
-
No extractors configured
-
Missing environment variable
-
Invalid connection string
-
Feature flag disabled
-
Service misconfigured
PERMANENT_NOT_FOUND
-
Application doesn’t exist
-
File deleted from storage
-
Extractor ID invalid
-
Stale reference to removed entity
-
HTTP: 404 (Not Found), 410 (Gone)
PERMANENT_AUTHORIZATION
-
Invalid API key
-
Expired access token
-
Insufficient permissions
-
Certificate expired
-
Service account disabled
-
HTTP: 401 (Unauthorized), 403 (Forbidden)
PERMANENT_BUSINESS_RULE
-
Duplicate operation attempt
-
Invalid state transition
-
Workflow already completed
-
Business constraint violation
-
HTTP: 409 (Conflict)
PERMANENT_MALFORMED
-
Message body is null/undefined
-
Unparseable JSON
-
Corrupted message data
-
Wrong message type on queue
-
Encoding issues