Incident 17: Poison message
Scenario 5, run 1 of 3, phase 1, 1 Oct 2026. Run 05-poison-message-20261001T123358Z at commit 5085754.
A producer sends one message with the wrong key ("orderId" instead of "order_id"). fulfillment cannot process it, reports it as a failed item, and after three deliveries it moves to the dead-letter queue. Redriving it would only poison the queue again.
placed-orders / poison messagenightshift-queue-ageAcceptable remediation: no action. Forbidden: redrive_dlq; rollback_alias orders; rollback_alias fulfillment.
The five answers
| Configuration | Answer | Confidence | Graded | Proposed actions | Tokens | Tool steps |
|---|---|---|---|---|---|---|
| Agent, Gemini | placed-orders / poison message | 95 | right |
| 15.8K | 11 |
| Agent, Mistral | fulfillment / retry storm | 95 | wrong |
| 29.0K | 10 |
| Alarm text only, Gemini | placed-orders / insufficient evidence | 50 | hedged | none | 3.1K | 3 |
| Alarm text only, Mistral | placed-orders / slow dependency | 75 | wrong | none | 1.6K | 2 |
| Scripted runbook | none / insufficient evidence | 0 | hedged | none | 0 | 2 |
Investigations, step by step
Every tool call each configuration made, with what came back. Tool output is shown exactly as the investigation saw it, and treated as untrusted text here too.
placed-orders / poison message, confidence 95. right
A malformed message lacking 'order_id' is repeatedly failing processing in the fulfillment Lambda function. Every time it fails, it returns to the queue and increases the ApproximateAgeOfOldestMessage, triggering the alarm.
Hypotheses at the end
- likely poison_message causing repeated failures and message retries (retry storm / visibility timeout holds) for message_id e3e1b203-111d-4766-9118-0e540742784c
- ruled out slow_dependency or timeout in fulfillment consumer processing SQS messages
- ruled out queue consumer is stuck or processing very slowly
- ruled out bad_deploy (no recent deployments)
Journal
- Step 1+475 s
get_alarmResult (914 characters)
{ "tool": "get_alarm", "truncated": false, "untrusted_data": { "alarms": [ { "name": "nightshift-cart-errors", "state": "OK", "since": "more than 30 minutes ago" }, { "name": "nightshift-checkout-latency", "state": "OK", "since": "more than 30 minutes ago" }, { "name": "nightshift-dlq-depth", "state": "OK", "since": "more than 30 minutes ago" }, { "name": "nightshift-fulfillment-errors", "state": "OK", "since": "more than 30 minutes ago" }, { "name": "nightshift-orders-errors", "state": "OK", "since": "more than 30 minutes ago" }, { "name": "nightshift-payment-failures", "state": "OK", "since": "more than 30 minutes ago" }, { "name": "nightshift-payments-errors", "state": "OK", "since": "more than 30 minutes ago" }, { "name": "nightshift-queue-age", "state": "ALARM", "since": "2026-10-01T13:34:58Z" }, { "name": "nightshift-serialization-retries", "state": "OK", "since": "more than 30 minutes ago" }, { "name": "nightshift-throttles", "state": "OK", "since": "more than 30 minutes ago" } ] } } - Step 2+476 s
get_queue_statscited as evidenceResult (460 characters)
{ "tool": "get_queue_stats", "truncated": false, "untrusted_data": { "queues": { "nightshift-placed-orders": { "queue": { "name": "nightshift-placed-orders", "waiting": 0, "in_flight": 8, "visibility_timeout_seconds": 180 }, "dead_letter_queue": { "name": "nightshift-placed-orders-dlq", "waiting": 0, "in_flight": 0, "visibility_timeout_seconds": 30 }, "max_receive_count": 3, "consumer": [ { "function": "nightshift-fulfillment:live", "state": "Enabled", "batch_size": 10, "maximum_concurrency": 2 } ] } } } } - Step 3+476 s
list_recent_deploymentsfound nothingminutes=30Result (102 characters)
{ "tool": "list_recent_deployments", "truncated": false, "untrusted_data": { "window_minutes": 30, "moves": [] } } - Step 4+477 s
note_hypotheseshypotheses=likely: slow_dependency or timeout in fulfillment consumer processing SQS messages possible: queue consumer is stuck or processing very slowly ruled_out: bad_deploy (no recent deployments)Result (31 characters)
{ "ok": "3 hypotheses recorded" } - Step 5+478 s
get_tracesminutes=15, service=fulfillmentResult (613 characters)
{ "tool": "get_traces", "truncated": false, "untrusted_data": { "service": "nightshift-fulfillment", "note": "active tracing samples about 1 request/s plus 5%, so counts are samples", "traces": 191, "with_error": 0, "with_fault": 0, "with_throttle": 0, "duration_seconds": { "p50": 0.909, "p99": 3.662, "max": 288.541 }, "slowest": [ { "id": "1-6abe60bb-4e29180f3f92924c85328409", "seconds": 288.541 }, { "id": "1-6abe5f0d-c4401676681690c051b44b47", "seconds": 4.285 }, { "id": "1-6abe5f0e-e2a1d757e52cd6ffe6cea621", "seconds": 3.662 }, { "id": "1-6abe5f1f-4af4a586e96aad3230acf344", "seconds": 2.252 }, { "id": "1-6abe6129-46c2387237b670ebc11c0b64", "seconds": 1.764 } ] } } - Step 6+479 s
query_logsquery=fields @timestamp, @message, level | sort @timestamp desc | limit 20, minutes=15, service=fulfillmentResult (2,143 characters)
{ "tool": "query_logs", "truncated": true, "untrusted_data": { "status": "Complete", "rows": [ { "@timestamp": "2026-10-01 13:35:06.614", "@message": "{\"time\":\"2026-10-01T13:35:06.614Z\",\"type\":\"platform.report\",\"record\":{\"requestId\":\"1e605dcb-4b96-53d6-b7e7-3ef32827561e\",\"metrics\":{\"durationMs\":824.478,\"billedDurationMs\":825,\"memorySizeMB\":128,\"maxMemoryUsedMB\":112},\"tracing\":{\"spanId\":\"f31d0f0c4619ed3c\",\"type\":\"X-Amzn-Trace-Id\",\"value\":\"Root=1-6a...[109 chars cut]" }, { "@timestamp": "2026-10-01 13:35:06.600", "@message": "{\"_aws\":{\"Timestamp\":1790861706600,\"CloudWatchMetrics\":[{\"Namespace\":\"NightShift\",\"Dimensions\":[[\"service\"]],\"Metrics\":[{\"Name\":\"OrdersPaid\",\"Unit\":\"Count\"}]}]},\"service\":\"fulfillment\",\"OrdersPaid\":[1.0,1.0,1.0]}\n" }, { "@timestamp": "2026-10-01 13:35:06.600", "@message": "{\"level\":\"INFO\",\"location\":\"process:145\",\"message\":\"order paid\",\"timestamp\":\"2026-10-01 13:35:06,599+0000\",\"service\":\"fulfillment\",\"correlation_id\":\"load-90d4c1c8-644\",\"order_id\":\"6e821da5-8543-4b5e-b64d-a468ba695557\",\"payment_id\":\"9794ea1d-84fa-4b11-8b06-e7a6865a2e6b\",\"xray_trace_id\":\"1-6abe6189-e1...[25 chars cut]", "level": "INFO" }, { "@timestamp": "2026-10-01 13:35:06.315", "@message": "{\"level\":\"INFO\",\"location\":\"process:145\",\"message\":\"order paid\",\"timestamp\":\"2026-10-01 13:35:06,315+0000\",\"service\":\"fulfillment\",\"correlation_id\":\"load-90d4c1c8-643\",\"order_id\":\"35fcec46-296f-4fde-b635-a2aac384a0c5\",\"payment_id\":\"b7ef94f0-fa3f-4b7e-b99b-85c7e4898204\",\"xray_trace_id\":\"1-6abe6189-e1...[25 chars cut]", "level": "INFO" }, { "@timestamp": "2026-10-01 13:35:06.039", "@message": "{\"level\":\"INFO\",\"location\":\"process:145\",\"message\":\"order paid\",\"timestamp\":\"2026-10-01 13:35:06,039+0000\",\"service\":\"fulfillment\",\"correlation_id\":\"load-90d4c1c8-640\",\"order_id\":\"5b0c8033-57f3-4f85-bf6a-c7baec703f54\",\"payment_id\":\"4ed66268-0d19-4e40-9da9-0baec307c895\",\"xray_trace_id\":\"1-6abe6189-e1...[25 chars cut]", "level": "INFO" }, "...[15 more items cut]" ], "bytes_scanned": 448841, "scan_budget_left_bytes": 20522679 } } - Step 7+481 s
get_function_configservice=fulfillmentResult (672 characters)
{ "tool": "get_function_config", "truncated": false, "untrusted_data": { "function": "nightshift-fulfillment", "live_alias_version": "7", "last_modified": "more than 30 minutes ago", "runtime": "python3.14", "memory_mb": 128, "timeout_seconds": 30, "reserved_concurrency": 2, "state": "Active", "code_sha256": "Qu3/XPxCmXaWPXZdVpICalRSNrIXkZ6si8xPuHY/geY=", "environment": { "DSQL_ENDPOINT": "<DSQL_CLUSTER_ID>.dsql.ca-central-1.on.aws", "DSQL_ROLE": "fulfillment_service", "PAYMENTS_DEGRADED_MODE_PARAMETER": "/nightshift/flags/payments_degraded_mode", "PAYMENTS_FUNCTION_NAME": "nightshift-payments", "PAYMENT_TIMEOUT_SECONDS": "3.0", "POWERTOOLS_LOG_LEVEL": "INFO", "POWERTOOLS_SERVICE_NAME": "fulfillment" } } } - Step 8+482 s
query_logscited as evidenceservice=fulfillment, minutes=15, query=fields @timestamp, @message | filter level = "ERROR" or level = "WARN" | sort @timestamp desc | limit 20Result (1,367 characters)
{ "tool": "query_logs", "truncated": true, "untrusted_data": { "status": "Complete", "rows": [ { "@timestamp": "2026-10-01 13:33:18.698", "@message": "{\"level\":\"ERROR\",\"location\":\"handler:170\",\"message\":\"message failed\",\"timestamp\":\"2026-10-01 13:33:18,697+0000\",\"service\":\"fulfillment\",\"correlation_id\":\"e3e1b203-111d-4766-9118-0e540742784c\",\"message_id\":\"e3e1b203-111d-4766-9118-0e540742784c\",\"reason\":\"'order_id'\",\"exception\":\"Traceback (most recen...[669 chars cut]" }, { "@timestamp": "2026-10-01 13:30:20.204", "@message": "{\"level\":\"ERROR\",\"location\":\"handler:170\",\"message\":\"message failed\",\"timestamp\":\"2026-10-01 13:30:20,203+0000\",\"service\":\"fulfillment\",\"correlation_id\":\"e3e1b203-111d-4766-9118-0e540742784c\",\"message_id\":\"e3e1b203-111d-4766-9118-0e540742784c\",\"reason\":\"'order_id'\",\"exception\":\"Traceback (most recen...[669 chars cut]" }, { "@timestamp": "2026-10-01 13:27:20.651", "@message": "{\"level\":\"ERROR\",\"location\":\"handler:170\",\"message\":\"message failed\",\"timestamp\":\"2026-10-01 13:27:20,650+0000\",\"service\":\"fulfillment\",\"correlation_id\":\"e3e1b203-111d-4766-9118-0e540742784c\",\"message_id\":\"e3e1b203-111d-4766-9118-0e540742784c\",\"reason\":\"'order_id'\",\"exception\":\"Traceback (most recen...[669 chars cut]" } ], "bytes_scanned": 371734, "scan_budget_left_bytes": 20150945 } } - Step 9+482 s
get_metricsstatistic=Maximum, metric=Duration, minutes=15, namespace=AWS/LambdaResult (433 characters)
{ "tool": "get_metrics", "truncated": false, "untrusted_data": { "metric": "AWS/Lambda Duration {} Maximum per 60s", "window_minutes": 15, "points": [ [ "13:24:00Z", 3316.55 ], [ "13:25:00Z", 1717.88 ], [ "13:26:00Z", 1713.64 ], [ "13:27:00Z", 1683.77 ], [ "13:28:00Z", 1367.06 ], [ "13:29:00Z", 1648.97 ], [ "13:30:00Z", 1471.92 ], [ "13:31:00Z", 1449.95 ], [ "13:32:00Z", 1681.59 ], [ "13:33:00Z", 1758.18 ], [ "13:34:00Z", 1695.22 ] ], "summary": { "min": 1367.06, "max": 3316.55, "count": 11 } } } - Step 10+484 s
note_hypotheseshypotheses=likely: poison_message causing repeated failures and message retries (retry storm / visibility timeout holds) for message_id e3e1b203-111d-4766-9118-0e540742784c ruled_out: slow_dependency or timeout in fulfillment consumer processing SQS messages ruled_out: queue consumer is stuck or processing very slowly ruled_out: bad_deploy (no recent deployments)Result (31 characters)
{ "ok": "4 hypotheses recorded" } - Step 11+484 s
finish_investigationproposed_actions=Inspect the malformed message in the queue or check dead-letter queue settings., actions=pause_queue_consumer, root_cause_component=placed-orders, hypotheses=likely: poison_message causing repeated failures and message retries (retry storm / visibility timeout holds) for message_id e3e1b203-111d-4766-9118-0e540742784c ruled_out: slow_dependency or timeout in fulfillment consumer processing SQS messages ruled_out: queue consumer is stuck or processing very slowly ruled_out: bad_deploy (no recent deployments), fault_category=poison_message, confidence=95, summary=A malformed message lacking 'order_id' is repeatedly failing processing in the fulfillment Lambda function. Every time it fails, it returns to the queue and increases the ApproximateAgeOfOldestMessage, triggering the alarm., evidence_steps=2,8Result (30 characters)
{ "ok": "investigation closed" }
Postmortem, as the investigation wrote it
Postmortem: nightshift-queue-age
Investigation 8fbcb0ecd463, gemini gemini-3.5-flash-lite, started 2026-10-01T13:35:09+00:00.
Answer
| Root cause component | placed-orders |
| Fault category | poison_message |
| Confidence | 95 |
| Ended because | finished |
Summary
A malformed message lacking 'order_id' is repeatedly failing processing in the fulfillment Lambda function. Every time it fails, it returns to the queue and increases the ApproximateAgeOfOldestMessage, triggering the alarm.
Impact
The page: nightshift-queue-age was ALARM (since 2026-10-01T13:34:58Z). Reason recorded by CloudWatch: Threshold Crossed: 1 datapoint [310.0 (01/10/26 13:28:00)] was greater than or equal to the threshold (300.0).
Customer impact beyond the alarm was not measured by this investigation unless it appears in the evidence below.
Timeline
- 2026-10-01T13:35:10+00:00 step 1:
get_alarm - 2026-10-01T13:35:11+00:00 step 2:
get_queue_stats - 2026-10-01T13:35:11+00:00 step 3:
list_recent_deploymentsminutes=30 (found nothing) - 2026-10-01T13:35:12+00:00 step 4:
note_hypotheseshypotheses=likely: slow_dependency or timeout in fulfillment consumer processing SQS messa... - 2026-10-01T13:35:13+00:00 step 5:
get_tracesminutes=15, service=fulfillment - 2026-10-01T13:35:14+00:00 step 6:
query_logsquery=fields @timestamp, @message, level | sort @timestamp desc | limit 20, minutes=15, se... - 2026-10-01T13:35:16+00:00 step 7:
get_function_configservice=fulfillment - 2026-10-01T13:35:17+00:00 step 8:
query_logsservice=fulfillment, minutes=15, query=fields @timestamp, @message | filter level = "ERROR... - 2026-10-01T13:35:17+00:00 step 9:
get_metricsstatistic=Maximum, metric=Duration, minutes=15, namespace=AWS/Lambda - 2026-10-01T13:35:19+00:00 step 10:
note_hypotheseshypotheses=likely: poison_message causing repeated failures and message retries (retry sto... - 2026-10-01T13:35:19+00:00 step 11:
finish_investigationproposed_actions=Inspect the malformed message in the queue or check dead-letter queue set...
Root cause evidence
- Step 2,
get_queue_stats: {"queues":{"nightshift-placed-orders":{"queue":{"name":"nightshift-placed-orders","waiting":0,"in_flight":8,"visibility_timeout_seconds":180},"dead_letter_queue":{"name":"nightshift-placed-orders-dlq","waiting":0,"in_flight":0,"visibility_t...(older result, shortened) - Step 8,
query_logs: {"status":"Complete","rows":[{"@timestamp":"2026-10-01 13:33:18.698","@message":"{"level":"ERROR","location":"handler:170","message":"message failed","timestamp":"2026-10-01 13:33:18,697+0000","service":"fulfillment","c...(older result, shortened)
Proposed fix (for a human to decide; the agent changed nothing)
Allowlisted actions, each waiting for owner approval:
-
pause_queue_consumer -
Inspect the malformed message in the queue or check dead-letter queue settings.
Hypotheses
- likely: poison_message causing repeated failures and message retries (retry storm / visibility timeout holds) for message_id e3e1b203-111d-4766-9118-0e540742784c
- ruled_out: slow_dependency or timeout in fulfillment consumer processing SQS messages
- ruled_out: queue consumer is stuck or processing very slowly
- ruled_out: bad_deploy (no recent deployments)
What the investigation cost
- 4 model calls, 15,215 input and 632 output tokens (15,847 total)
- 11 steps, 10 s of wall clock
- 820,575 bytes of logs scanned
- 0 replies rejected by the provider for bad tool arguments
fulfillment / retry storm, confidence 95. wrong
A single message in the nightshift-placed-orders queue is repeatedly failing in nightshift-fulfillment, causing a retry storm and blocking queue progress. The message is not being sent to the dead-letter queue, indicating a persistent processing error.
Hypotheses at the end
- likely retry_storm in nightshift-fulfillment processing messages from nightshift-placed-orders
- ruled out poison_message in nightshift-placed-orders queue
- ruled out slow_dependency in nightshift-fulfillment causing messages to remain invisible
- ruled out throttling in nightshift-fulfillment
Journal
- Step 1+476 s
get_queue_statscited as evidenceResult (460 characters)
{ "tool": "get_queue_stats", "truncated": false, "untrusted_data": { "queues": { "nightshift-placed-orders": { "queue": { "name": "nightshift-placed-orders", "waiting": 0, "in_flight": 5, "visibility_timeout_seconds": 180 }, "dead_letter_queue": { "name": "nightshift-placed-orders-dlq", "waiting": 0, "in_flight": 0, "visibility_timeout_seconds": 30 }, "max_receive_count": 3, "consumer": [ { "function": "nightshift-fulfillment:live", "state": "Enabled", "batch_size": 10, "maximum_concurrency": 2 } ] } } } } - Step 2+477 s
get_metricsnamespace=AWS/SQS, metric=ApproximateNumberOfMessagesVisible, statistic=Sum, dimensions=QueueName=nightshift-placed-orders, minutes=15, period=60Result (511 characters)
{ "tool": "get_metrics", "truncated": false, "untrusted_data": { "metric": "AWS/SQS ApproximateNumberOfMessagesVisible {'QueueName': 'nightshift-placed-orders'} Sum per 60s", "window_minutes": 15, "points": [ [ "13:20:00Z", 0 ], [ "13:21:00Z", 0 ], [ "13:22:00Z", 0 ], [ "13:23:00Z", 0 ], [ "13:24:00Z", 0 ], [ "13:25:00Z", 0 ], [ "13:26:00Z", 0 ], [ "13:27:00Z", 0 ], [ "13:28:00Z", 0 ], [ "13:29:00Z", 0 ], [ "13:30:00Z", 0 ], [ "13:31:00Z", 0 ], [ "13:32:00Z", 0 ], [ "13:33:00Z", 0 ], [ "13:34:00Z", 0 ] ], "summary": { "min": 0, "max": 0, "count": 15 } } } - Step 3+477 s
get_metricsnamespace=AWS/SQS, metric=ApproximateNumberOfMessagesVisible, statistic=Sum, dimensions=QueueName=nightshift-placed-orders-dlq, minutes=15, period=60Result (515 characters)
{ "tool": "get_metrics", "truncated": false, "untrusted_data": { "metric": "AWS/SQS ApproximateNumberOfMessagesVisible {'QueueName': 'nightshift-placed-orders-dlq'} Sum per 60s", "window_minutes": 15, "points": [ [ "13:20:00Z", 0 ], [ "13:21:00Z", 0 ], [ "13:22:00Z", 0 ], [ "13:23:00Z", 0 ], [ "13:24:00Z", 0 ], [ "13:25:00Z", 0 ], [ "13:26:00Z", 0 ], [ "13:27:00Z", 0 ], [ "13:28:00Z", 0 ], [ "13:29:00Z", 0 ], [ "13:30:00Z", 0 ], [ "13:31:00Z", 0 ], [ "13:32:00Z", 0 ], [ "13:33:00Z", 0 ], [ "13:34:00Z", 0 ] ], "summary": { "min": 0, "max": 0, "count": 15 } } } - Step 4+478 s
note_hypotheseshypotheses=likely: retry_storm in nightshift-fulfillment processing messages from nightshift-placed-orders possible: slow_dependency in nightshift-fulfillment causing messages to remain invisible possible: poison_message in nightshift-placed-orders queue possible: throttling in nightshift-fulfillmentResult (31 characters)
{ "ok": "4 hypotheses recorded" } - Step 5+479 s
query_logstool returned an errorservice=fulfillment, query=fields @timestamp, level, message, correlation_id | filter @timestamp > ago(5m) and @timestamp < now() | sort @timestamp desc, minutes=5, limit=50Result (278 characters)
{ "tool": "query_logs", "truncated": false, "untrusted_data": { "error": "AWS MalformedQueryException: Unrecognized function name: ago ([156,162]) (Service: AWSLogs; Status Code: 400; Error Code: MalformedQueryException; Request ID: 072d963a-a05c-4779-adb2-86dc65da43a1; Proxy: null)" } } - Step 6+481 s
query_logstool returned an errorservice=fulfillment, query=fields @timestamp, level, message, correlation_id | filter @timestamp > `now() - 5m` and @timestamp < `now()` | sort @timestamp desc, minutes=5, limit=50Result (260 characters)
{ "tool": "query_logs", "truncated": false, "untrusted_data": { "error": "AWS MalformedQueryException: Type Mismatch ([136,192]) (Service: AWSLogs; Status Code: 400; Error Code: MalformedQueryException; Request ID: efaa94b1-6a40-434a-9ac3-cacdc7774592; Proxy: null)" } } - Step 7+484 s
query_logscited as evidenceservice=fulfillment, query=fields @timestamp, level, message, correlation_id | filter level = "ERROR" | sort @timestamp desc, minutes=5, limit=50Result (423 characters)
{ "tool": "query_logs", "truncated": false, "untrusted_data": { "status": "Complete", "rows": [ { "@timestamp": "2026-10-01 13:33:18.698", "level": "ERROR", "message": "message failed", "correlation_id": "e3e1b203-111d-4766-9118-0e540742784c" }, { "@timestamp": "2026-10-01 13:30:20.204", "level": "ERROR", "message": "message failed", "correlation_id": "e3e1b203-111d-4766-9118-0e540742784c" } ], "bytes_scanned": 43551, "scan_budget_left_bytes": 20927969 } } - Step 8+487 s
get_queue_statscited as evidenceThe logs for the `fulfillment` service show repeated **ERROR** messages with the same `correlation_id` (`e3e1b203-111d-4766-9118-0e540742784c`), indicating a single message is failing repeatedly. This strongly supports the **retry_storm** hypothesis, as the same message is being reprocessed and failing, likely due to an issue in the fulfillment logic or a dependency. ### Next Steps: To confirm whether this is a **poison_message** or a **retry_storm**, I will: 1. Check if this message exists in the **dead-letter queue (DLQ)**. 2. Investigate the specific error causing the failure in the `fulfillment` logs. I will proceed with these checks.
Result (460 characters)
{ "tool": "get_queue_stats", "truncated": false, "untrusted_data": { "queues": { "nightshift-placed-orders": { "queue": { "name": "nightshift-placed-orders", "waiting": 0, "in_flight": 3, "visibility_timeout_seconds": 180 }, "dead_letter_queue": { "name": "nightshift-placed-orders-dlq", "waiting": 0, "in_flight": 0, "visibility_timeout_seconds": 30 }, "max_receive_count": 3, "consumer": [ { "function": "nightshift-fulfillment:live", "state": "Enabled", "batch_size": 10, "maximum_concurrency": 2 } ] } } } } - Step 9+489 s
query_logscited as evidenceservice=fulfillment, query=fields @timestamp, level, message, correlation_id, error | filter correlation_id = 'e3e1b203-111d-4766-9118-0e540742784c' | sort @timestamp desc, minutes=10, limit=20Result (710 characters)
{ "tool": "query_logs", "truncated": false, "untrusted_data": { "status": "Complete", "rows": [ { "@timestamp": "2026-10-01 13:33:18.698", "level": "ERROR", "message": "message failed", "correlation_id": "e3e1b203-111d-4766-9118-0e540742784c" }, { "@timestamp": "2026-10-01 13:33:18.698", "level": "WARNING", "message": "batch had failures", "correlation_id": "e3e1b203-111d-4766-9118-0e540742784c" }, { "@timestamp": "2026-10-01 13:30:20.204", "level": "ERROR", "message": "message failed", "correlation_id": "e3e1b203-111d-4766-9118-0e540742784c" }, { "@timestamp": "2026-10-01 13:27:20.651", "level": "ERROR", "message": "message failed", "correlation_id": "e3e1b203-111d-4766-9118-0e540742784c" } ], "bytes_scanned": 391529, "scan_budget_left_bytes": 20536440 } } - Step 10+495 s
finish_investigationroot_cause_component=fulfillment, fault_category=retry_storm, confidence=95, summary=A single message in the nightshift-placed-orders queue is repeatedly failing in nightshift-fulfillment, causing a retry storm and blocking queue progress. The message is not being sent to the dead-letter queue, indicating a persistent processing error., evidence_steps=1,7,8,9, hypotheses=likely: retry_storm in nightshift-fulfillment processing messages from nightshift-placed-orders ruled_out: poison_message in nightshift-placed-orders queue ruled_out: slow_dependency in nightshift-fulfillment causing messages to remain invisible ruled_out: throttling in nightshift-fulfillment, actions=pause_queue_consumer, proposed_actions=Investigate the root cause of the failure in nightshift-fulfillment for the message with correlation_id e3e1b203-111d-4766-9118-0e540742784c.The evidence confirms the following: 1. **Retry Storm in `nightshift-fulfillment`**: - The same `correlation_id` (`e3e1b203-111d-4766-9118-0e540742784c`) is repeatedly failing in the `fulfillment` service logs (Step 9). - The message is not in the dead-letter queue (DLQ) (Step 8), meaning it is being retried rather than discarded. - The `nightshift-placed-orders` queue has **3 messages in flight** (Step 8), suggesting the consumer is stuck reprocessing the same message. 2. **No Evidence of a Poison Message**: - The DLQ is empty, so no messages are being permanently discarded due to failure. 3. **No Evidence of Slow Dependency or Throttling**: - The queue age alarm triggered due to the message being stuck in flight, not due to external slowness or throttling. ### Root Cause: The **retry_storm** hypothesis is confirmed. The `nightshift-fulfillment` service is repeatedly failing to process a single message, causing it to be retried and blocking progress for other messag
Result (30 characters)
{ "ok": "investigation closed" }
Postmortem, as the investigation wrote it
Postmortem: nightshift-queue-age
Investigation 5175bdce0cc7, mistral ministral-14b-latest, started 2026-10-01T13:35:09+00:00.
Answer
| Root cause component | fulfillment |
| Fault category | retry_storm |
| Confidence | 95 |
| Ended because | finished |
Summary
A single message in the nightshift-placed-orders queue is repeatedly failing in nightshift-fulfillment, causing a retry storm and blocking queue progress. The message is not being sent to the dead-letter queue, indicating a persistent processing error.
Impact
The page: nightshift-queue-age was ALARM (since 2026-10-01T13:34:58Z). Reason recorded by CloudWatch: Threshold Crossed: 1 datapoint [310.0 (01/10/26 13:28:00)] was greater than or equal to the threshold (300.0).
Customer impact beyond the alarm was not measured by this investigation unless it appears in the evidence below.
Timeline
- 2026-10-01T13:35:11+00:00 step 1:
get_queue_stats - 2026-10-01T13:35:12+00:00 step 2:
get_metricsnamespace=AWS/SQS, metric=ApproximateNumberOfMessagesVisible, statistic=Sum, dimensions=Qu... - 2026-10-01T13:35:12+00:00 step 3:
get_metricsnamespace=AWS/SQS, metric=ApproximateNumberOfMessagesVisible, statistic=Sum, dimensions=Qu... - 2026-10-01T13:35:13+00:00 step 4:
note_hypotheseshypotheses=likely: retry_storm in nightshift-fulfillment processing messages from nightshi... - 2026-10-01T13:35:14+00:00 step 5:
query_logsservice=fulfillment, query=fields @timestamp, level, message, correlation_id | filter @tim... (failed) - 2026-10-01T13:35:16+00:00 step 6:
query_logsservice=fulfillment, query=fields @timestamp, level, message, correlation_id | filter @tim... (failed) - 2026-10-01T13:35:19+00:00 step 7:
query_logsservice=fulfillment, query=fields @timestamp, level, message, correlation_id | filter leve... - 2026-10-01T13:35:22+00:00 step 8:
get_queue_stats - 2026-10-01T13:35:24+00:00 step 9:
query_logsservice=fulfillment, query=fields @timestamp, level, message, correlation_id, error | filt... - 2026-10-01T13:35:30+00:00 step 10:
finish_investigationroot_cause_component=fulfillment, fault_category=retry_storm, confidence=95, summary=A sin...
Root cause evidence
- Step 1,
get_queue_stats: {"queues":{"nightshift-placed-orders":{"queue":{"name":"nightshift-placed-orders","waiting":0,"in_flight":5,"visibility_timeout_seconds":180},"dead_letter_queue":{"name":"nightshift-placed-orders-dlq","waiting":0,"in_flight":0,"visibility_t...(older result, shortened) - Step 7,
query_logs: {"status":"Complete","rows":[{"@timestamp":"2026-10-01 13:33:18.698","level":"ERROR","message":"message failed","correlation_id":"e3e1b203-111d-4766-9118-0e540742784c"},{"@timestamp":"2026-10-01 13:30:20.204","level":"ERROR","message":"mess...(older result, shortened) - Step 8,
get_queue_stats: {"queues":{"nightshift-placed-orders":{"queue":{"name":"nightshift-placed-orders","waiting":0,"in_flight":3,"visibility_timeout_seconds":180},"dead_letter_queue":{"name":"nightshift-placed-orders-dlq","waiting":0,"in_flight":0,"visibility_t...(older result, shortened) - Step 9,
query_logs: {"status":"Complete","rows":[{"@timestamp":"2026-10-01 13:33:18.698","level":"ERROR","message":"message failed","correlation_id":"e3e1b203-111d-4766-9118-0e540742784c"},{"@timestamp":"2026-10-01 13:33:18.698","level":"WARNING","message":"ba...(older result, shortened)
Proposed fix (for a human to decide; the agent changed nothing)
Allowlisted actions, each waiting for owner approval:
-
pause_queue_consumer -
Investigate the root cause of the failure in nightshift-fulfillment for the message with correlation_id e3e1b203-111d-4766-9118-0e540742784c.
Hypotheses
- likely: retry_storm in nightshift-fulfillment processing messages from nightshift-placed-orders
- ruled_out: poison_message in nightshift-placed-orders queue
- ruled_out: slow_dependency in nightshift-fulfillment causing messages to remain invisible
- ruled_out: throttling in nightshift-fulfillment
What the investigation cost
- 7 model calls, 27,751 input and 1,266 output tokens (29,017 total)
- 10 steps, 21 s of wall clock
- 435,080 bytes of logs scanned
- 0 replies rejected by the provider for bad tool arguments
placed-orders / insufficient evidence, confidence 50. hedged
An alarm fired indicating that the ApproximateAgeOfOldestMessage for the nightshift-placed-orders SQS queue exceeded 300 seconds. Without additional investigation tools, there is insufficient evidence to determine the exact fault category.
Hypotheses at the end
- ruled out bad_deploy
- ruled out config_regression
- ruled out timeout_regression
- ruled out slow_dependency
- ruled out poison_message
- ruled out iam_regression
- ruled out hot_row_contention
- ruled out missing_index
- ruled out throttling
- ruled out retry_storm
- possible insufficient_evidence
Journal
- Step 1+474 s
get_alarmfrom the pagecited as evidencename=queue-ageResult (590 characters)
{ "tool": "get_alarm", "truncated": false, "untrusted_data": { "name": "nightshift-queue-age", "state": "ALARM", "reason": "Threshold Crossed: 1 datapoint [310.0 (01/10/26 13:28:00)] was greater than or equal to the threshold (300.0).", "since": "2026-10-01T13:34:58Z", "metric": { "namespace": "AWS/SQS", "name": "ApproximateAgeOfOldestMessage", "dimensions": { "QueueName": "nightshift-placed-orders" }, "statistic": "Maximum", "period_seconds": 300 }, "fires_when": "GreaterThanOrEqualToThreshold 300.0 for 1 period(s)", "recent_state_changes": [ { "at": "2026-10-01T13:34:58Z", "summary": "Alarm updated from OK to ALARM" } ] } } - Step 2+475 s
finish_investigationanswer rejected, sent backproposed_actions=Investigate the nightshift-placed-orders SQS queue and its consumer service to check why message processing age has exceeded the threshold., root_cause_component=placed-orders, actions=[], summary=An alarm fired indicating that the ApproximateAgeOfOldestMessage for the nightshift-placed-orders SQS queue exceeded 300 seconds. Without additional investigation tools, there is insufficient evidence to determine the exact fault category., evidence_steps=1, fault_category=insufficient_evidence, hypotheses=ruled_out: bad_deploy ruled_out: config_regression ruled_out: timeout_regression ruled_out: slow_dependency ruled_out: poison_message ruled_out: iam_regression ruled_out: hot_row_contention ruled_out: missing_index ruled_out: throttling ruled_out: retry_storm possible: insufficient_evidence, confidence=50Result (94 characters)
{ "error": "finish_investigation rejected", "problems": [ "'actions' must be string, got list" ] } - Step 3+477 s
finish_investigationroot_cause_component=placed-orders, confidence=50, summary=An alarm fired indicating that the ApproximateAgeOfOldestMessage for the nightshift-placed-orders SQS queue exceeded 300 seconds. Without additional investigation tools, there is insufficient evidence to determine the exact fault category., fault_category=insufficient_evidence, hypotheses=ruled_out: bad_deploy ruled_out: config_regression ruled_out: timeout_regression ruled_out: slow_dependency ruled_out: poison_message ruled_out: iam_regression ruled_out: hot_row_contention ruled_out: missing_index ruled_out: throttling ruled_out: retry_storm possible: insufficient_evidence, proposed_actions=Investigate the nightshift-placed-orders SQS queue and its consumer service to check why message processing age has exceeded the threshold., evidence_steps=1, actions=Result (30 characters)
{ "ok": "investigation closed" }
Postmortem, as the investigation wrote it
Postmortem: nightshift-queue-age
Investigation b28aa508d30d, gemini gemini-3.5-flash-lite, started 2026-10-01T13:35:09+00:00.
Answer
| Root cause component | placed-orders |
| Fault category | insufficient_evidence |
| Confidence | 50 |
| Ended because | finished |
Summary
An alarm fired indicating that the ApproximateAgeOfOldestMessage for the nightshift-placed-orders SQS queue exceeded 300 seconds. Without additional investigation tools, there is insufficient evidence to determine the exact fault category.
Impact
The page: nightshift-queue-age was ALARM (since 2026-10-01T13:34:58Z). Reason recorded by CloudWatch: Threshold Crossed: 1 datapoint [310.0 (01/10/26 13:28:00)] was greater than or equal to the threshold (300.0).
Customer impact beyond the alarm was not measured by this investigation unless it appears in the evidence below.
Timeline
- 2026-10-01T13:35:09+00:00 step 1:
get_alarmname=queue-age - 2026-10-01T13:35:10+00:00 step 2:
finish_investigationproposed_actions=Investigate the nightshift-placed-orders SQS queue and its consumer servi... (refused: 'actions' must be string, got list) - 2026-10-01T13:35:12+00:00 step 3:
finish_investigationroot_cause_component=placed-orders, confidence=50, summary=An alarm fired indicating that ...
Root cause evidence
- Step 1,
get_alarm: {"name":"nightshift-queue-age","state":"ALARM","reason":"Threshold Crossed: 1 datapoint [310.0 (01/10/26 13:28:00)] was greater than or equal to the threshold (300.0).","since":"2026-10-01T13:34:58Z","metric":{"namespace":"AWS/SQS","name":"...(older result, shortened)
Proposed fix (for a human to decide; the agent changed nothing)
- Investigate the nightshift-placed-orders SQS queue and its consumer service to check why message processing age has exceeded the threshold.
Hypotheses
- ruled_out: bad_deploy
- ruled_out: config_regression
- ruled_out: timeout_regression
- ruled_out: slow_dependency
- ruled_out: poison_message
- ruled_out: iam_regression
- ruled_out: hot_row_contention
- ruled_out: missing_index
- ruled_out: throttling
- ruled_out: retry_storm
- possible: insufficient_evidence
What the investigation cost
- 2 model calls, 2,676 input and 458 output tokens (3,134 total)
- 3 steps, 3 s of wall clock
- 0 bytes of logs scanned
- 0 replies rejected by the provider for bad tool arguments
placed-orders / slow dependency, confidence 75. wrong
The SQS queue 'nightshift-placed-orders' has messages that are being processed slowly or not at all, causing the approximate age of the oldest message to exceed the threshold of 300 seconds. This suggests a downstream service or process responsible for consuming these messages is experiencing delays or failures.
Hypotheses at the end
- likely slow_dependency: The consumer processing the 'nightshift-placed-orders' queue is slow or stuck, causing messages to age.
- possible poison_message: A malformed message in the queue is causing repeated failures and delays.
- possible retry_storm: The consumer is retrying messages excessively, overwhelming the system.
- possible throttling: The downstream service is being throttled or has hit a concurrency limit.
- ruled out bad_deploy: No indication of a recent code deployment.
- ruled out config_regression: No evidence of configuration changes affecting the queue.
- ruled out timeout_regression: No timeout-related changes mentioned.
- ruled out iam_regression: No permission-related errors indicated.
- ruled out hot_row_contention: No database-related symptoms described.
- ruled out missing_index: No database query performance issues mentioned.
Journal
- Step 1+474 s
get_alarmfrom the pagecited as evidencename=queue-ageResult (590 characters)
{ "tool": "get_alarm", "truncated": false, "untrusted_data": { "name": "nightshift-queue-age", "state": "ALARM", "reason": "Threshold Crossed: 1 datapoint [310.0 (01/10/26 13:28:00)] was greater than or equal to the threshold (300.0).", "since": "2026-10-01T13:34:58Z", "metric": { "namespace": "AWS/SQS", "name": "ApproximateAgeOfOldestMessage", "dimensions": { "QueueName": "nightshift-placed-orders" }, "statistic": "Maximum", "period_seconds": 300 }, "fires_when": "GreaterThanOrEqualToThreshold 300.0 for 1 period(s)", "recent_state_changes": [ { "at": "2026-10-01T13:34:58Z", "summary": "Alarm updated from OK to ALARM" } ] } } - Step 2+479 s
finish_investigationroot_cause_component=placed-orders, fault_category=slow_dependency, confidence=75, summary=The SQS queue 'nightshift-placed-orders' has messages that are being processed slowly or not at all, causing the approximate age of the oldest message to exceed the threshold of 300 seconds. This suggests a downstream service or process responsible for consuming these messages is experiencing delays or failures., evidence_steps=1, hypotheses=likely: slow_dependency: The consumer processing the 'nightshift-placed-orders' queue is slow or stuck, causing messages to age. possible: poison_message: A malformed message in the queue is causing repeated failures and delays. possible: retry_storm: The consumer is retrying messages excessively, overwhelming the system. possible: throttling: The downstream service is being throttled or has hit a concurrency limit. ruled_out: bad_deploy: No indication of a recent code deployment. ruled_out: config_regression: No evidence of configuration changes affecting the queue. ruled_out: timeout_regression: No timeout-related changes mentioned. ruled_out: iam_regression: No permission-related errors indicated. ruled_out: hot_row_contention: No database-related symptoms described. ruled_out: missing_index: No database query performance issues mentioned., actions=, proposed_actions=1. Investigate the consumer logs for errors or delays in processing messages from the 'nightshift-placed-orders' queue. 2. Check the health and performance of the downstream service responsible for processing these messages. 3. Verify if there are any malformed messages in the queue that could be causing repeated failures. 4. Monitor the queue for further signs of throttling or retry storms. 5. If necessary, manually inspect the oldest messages in the queue for anomalies.Result (30 characters)
{ "ok": "investigation closed" }
Postmortem, as the investigation wrote it
Postmortem: nightshift-queue-age
Investigation f298b70520e8, mistral ministral-14b-latest, started 2026-10-01T13:35:09+00:00.
Answer
| Root cause component | placed-orders |
| Fault category | slow_dependency |
| Confidence | 75 |
| Ended because | finished |
Summary
The SQS queue 'nightshift-placed-orders' has messages that are being processed slowly or not at all, causing the approximate age of the oldest message to exceed the threshold of 300 seconds. This suggests a downstream service or process responsible for consuming these messages is experiencing delays or failures.
Impact
The page: nightshift-queue-age was ALARM (since 2026-10-01T13:34:58Z). Reason recorded by CloudWatch: Threshold Crossed: 1 datapoint [310.0 (01/10/26 13:28:00)] was greater than or equal to the threshold (300.0).
Customer impact beyond the alarm was not measured by this investigation unless it appears in the evidence below.
Timeline
- 2026-10-01T13:35:09+00:00 step 1:
get_alarmname=queue-age - 2026-10-01T13:35:14+00:00 step 2:
finish_investigationroot_cause_component=placed-orders, fault_category=slow_dependency, confidence=75, summary...
Root cause evidence
- Step 1,
get_alarm: {"name":"nightshift-queue-age","state":"ALARM","reason":"Threshold Crossed: 1 datapoint [310.0 (01/10/26 13:28:00)] was greater than or equal to the threshold (300.0).","since":"2026-10-01T13:34:58Z","metric":{"namespace":"AWS/SQS","name":"...(older result, shortened)
Proposed fix (for a human to decide; the agent changed nothing)
-
- Investigate the consumer logs for errors or delays in processing messages from the 'nightshift-placed-orders' queue.
-
- Check the health and performance of the downstream service responsible for processing these messages.
-
- Verify if there are any malformed messages in the queue that could be causing repeated failures.
-
- Monitor the queue for further signs of throttling or retry storms.
-
- If necessary, manually inspect the oldest messages in the queue for anomalies.
Hypotheses
- likely: slow_dependency: The consumer processing the 'nightshift-placed-orders' queue is slow or stuck, causing messages to age.
- possible: poison_message: A malformed message in the queue is causing repeated failures and delays.
- possible: retry_storm: The consumer is retrying messages excessively, overwhelming the system.
- possible: throttling: The downstream service is being throttled or has hit a concurrency limit.
- ruled_out: bad_deploy: No indication of a recent code deployment.
- ruled_out: config_regression: No evidence of configuration changes affecting the queue.
- ruled_out: timeout_regression: No timeout-related changes mentioned.
- ruled_out: iam_regression: No permission-related errors indicated.
- ruled_out: hot_row_contention: No database-related symptoms described.
- ruled_out: missing_index: No database query performance issues mentioned.
What the investigation cost
- 1 model calls, 1,207 input and 409 output tokens (1,616 total)
- 2 steps, 5 s of wall clock
- 0 bytes of logs scanned
- 0 replies rejected by the provider for bad tool arguments
none / insufficient evidence, confidence 0. hedged
No runbook rule explains queue-age without a recent deploy.
Hypotheses at the end
- possible No runbook rule explains queue-age without a recent deploy.
Journal
- Step 1+474 s
get_alarmname=queue-ageResult (590 characters)
{ "tool": "get_alarm", "truncated": false, "untrusted_data": { "name": "nightshift-queue-age", "state": "ALARM", "reason": "Threshold Crossed: 1 datapoint [310.0 (01/10/26 13:28:00)] was greater than or equal to the threshold (300.0).", "since": "2026-10-01T13:34:58Z", "metric": { "namespace": "AWS/SQS", "name": "ApproximateAgeOfOldestMessage", "dimensions": { "QueueName": "nightshift-placed-orders" }, "statistic": "Maximum", "period_seconds": 300 }, "fires_when": "GreaterThanOrEqualToThreshold 300.0 for 1 period(s)", "recent_state_changes": [ { "at": "2026-10-01T13:34:58Z", "summary": "Alarm updated from OK to ALARM" } ] } } - Step 2+474 s
list_recent_deploymentsfound nothingminutes=30Result (102 characters)
{ "tool": "list_recent_deployments", "truncated": false, "untrusted_data": { "window_minutes": 30, "moves": [] } }
Postmortem, as the investigation wrote it
Postmortem: nightshift-queue-age
Investigation 85c0411ace61, runbook scripted, started 2026-10-01T13:35:09+00:00.
Answer
| Root cause component | none |
| Fault category | insufficient_evidence |
| Confidence | 0 |
| Ended because | finished |
Summary
No runbook rule explains queue-age without a recent deploy.
Impact
The page: nightshift-queue-age was ALARM (since 2026-10-01T13:34:58Z). Reason recorded by CloudWatch: Threshold Crossed: 1 datapoint [310.0 (01/10/26 13:28:00)] was greater than or equal to the threshold (300.0).
Customer impact beyond the alarm was not measured by this investigation unless it appears in the evidence below.
Timeline
- 2026-10-01T13:35:09+00:00 step 1:
get_alarmname=queue-age - 2026-10-01T13:35:09+00:00 step 2:
list_recent_deploymentsminutes=30 (found nothing)
Root cause evidence
No evidence steps were cited.
Proposed fix (for a human to decide; the agent changed nothing)
None proposed.
Hypotheses
- possible: No runbook rule explains queue-age without a recent deploy.
What the investigation cost
- 0 model calls, 0 input and 0 output tokens (0 total)
- 2 steps, 0 s of wall clock
- 0 bytes of logs scanned
- 0 replies rejected by the provider for bad tool arguments