Based on the DEA-C01 exam guideReport an error
When a pipeline stops, the ability to reconstruct "what happened" is half of operations. Of the material for that, the part that records "what people and systems told AWS to do" is CloudTrail.
| Event type | What it holds | Recorded by default? |
|---|---|---|
| Management events | Control-plane operations such as creating, modifying, and deleting resources and IAM changes | Recorded |
| Data events | Data-plane operations such as S3 object GET/PUT, Lambda Invoke, and DynamoDB item-level operations | Not recorded (turn on by specifying resource types) |
| Network activity events | API calls made through VPC endpoints | Not recorded |
| Insights events | Unusual API call volume or error rates | Not recorded |
Question: "Who DROPped the curated table early yesterday morning?"
→ In CloudTrail, narrow eventSource=glue.amazonaws.com, eventName=DeleteTable
by time and userIdentity💡 Related theory: CloudWatch Logs holds logs written by the application, while CloudTrail records AWS API calls. A
DROP TABLEstatement executed in Athena remains in the Athena query history, and theglue:DeleteTablethat was called as a result remains in CloudTrail. Remembering that one incident leaves traces in two places in different forms speeds up tracing.
| Log | What it records | Default state | Clue for choosing it |
|---|---|---|---|
| CloudTrail management events | API calls that change resources, permissions, and settings | On (90-day lookup) | "Who changed the table, policy, or key?" |
| CloudTrail data events | Object- and item-level access | Off; billed when on | "Who read this object?" |
| S3 server access logs | Requests that arrived at a bucket | Off; delivery within a few hours (best effort) | When you must see authentication-failed requests, or lifecycle transitions and expirations |
| CloudWatch Logs | Text output by jobs and functions | Depends on the service and settings | "Why did it fail? (stack trace)" |
AccessDenied). If you need to see authentication failures too, use server access logs.JSON logs that a trail has accumulated in S3 can be turned into an Athena table and searched with SQL.
-- Calls that deleted or changed Glue catalog tables in the past two days
SELECT eventtime, useridentity.arn AS who, eventname, sourceipaddress, requestparameters
FROM cloudtrail_logs
WHERE eventsource = 'glue.amazonaws.com'
AND eventname IN ('DeleteTable', 'UpdateTable', 'BatchDeleteTable')
AND eventtime >= '2026-06-25T00:00:00Z'
ORDER BY eventtime DESC;userIdentity. To find the actual person, trace back one more step to the AssumeRole event that created that session.When an incident occurs, do not open the code first; narrow from top to bottom.
Step Functions execution → TransformJob failed
→ CloudWatch Logs (Glue): "AnalysisException: cannot resolve 'email'"
→ Cause: upstream renamed the email column to user_email
→ Action: fix the mapping + add a schema validation gate| Symptom (log or error) | Cause | Action |
|---|---|---|
ProvisionedThroughputExceededException, Rate exceeded, ThrottlingException | API or throughput limit exceeded | Backoff retries, add capacity, batch the calls |
| Spark executor OOM, tasks die repeatedly | Partitions too large, or skew | Adjust partition count, distribute keys, use workers with more memory |
| Only some tasks take unusually long | Data skew | Check shuffle metrics, use salting or broadcast joins |
AccessDenied | One of IAM policy, Lake Formation permission, or KMS key policy is missing | Check the three layers in order (Week 9) |
| A job runs a long time and is forcibly terminated | Glue job timeout | Check the timeout value. If left blank, it is 2,880 minutes for Glue 4.0 and below and 480 minutes for 5.0 and above |
| Starting the same job concurrently causes an error | Exceeded the maximum concurrent runs (default 1) | Raise concurrent runs or queue job runs |
| A job inside a VPC times out calling KMS | No path to KMS | KMS VPC endpoint or NAT |
| Column not found, type mismatch | Upstream schema change | Fix the mapping, schema validation gate |
In distributed systems, transient errors are normal. The key is to distinguish errors worth retrying from permanent errors.
"Retry": [{
"ErrorEquals": ["ThrottlingException", "Glue.ConcurrentRunsExceededException"],
"IntervalSeconds": 5,
"BackoffRate": 2.0,
"MaxAttempts": 4,
"MaxDelaySeconds": 60,
"JitterStrategy": "FULL"
}],
"Catch": [{
"ErrorEquals": ["States.ALL"],
"ResultPath": "$.error",
"Next": "QuarantineAndNotify"
}]| Field | Default | Meaning |
|---|---|---|
IntervalSeconds | 1 | Time to wait before the first retry |
MaxAttempts | 3 | Maximum number of retries. 0 means no retry |
BackoffRate | 2.0 | Multiplier applied to the interval on each retry |
MaxDelaySeconds | No limit | Upper bound on how far the interval grows |
JitterStrategy | NONE | With FULL, waits a random time between 0 and the computed interval |
FULL explicitly.States.ALL matches every error name, but it must appear alone in its array and as the last entry. States.TaskFailed matches every error except States.Timeout.States.Runtime (for example, applying a path to a null payload) can be neither retried nor caught and fails the execution. States.DataLimitExceeded is not caught by States.ALL and must be named explicitly to be caught.💡 Related theory: Retries are safe only for idempotent operations. Blindly retrying a non-idempotent operation such as "increase the balance by 100" applies it twice. Protect it with an idempotency key or a conditional write. For a load job, partition overwrite or MERGE instead of append plays the same role.
| Executor | Default retry | If all attempts fail |
|---|---|---|
| Step Functions Task | No retry if Retry is not specified | Catch; if none, the execution fails |
| Lambda asynchronous invocation | On function error, 2 more attempts (after 1 minute, then after another 2 minutes). Throttles and system errors are retried by default for up to 6 hours | The event is discarded. It remains only if you attach a DLQ or an on-failure destination |
| Lambda stream event source mapping (Kinesis) | Retries the same batch until the records expire | The shard is blocked. Isolate with a retry limit, batch splitting, or an on-failure destination |
| SQS consumer | The message becomes visible again after the visibility timeout passes | Goes to the DLQ when maxReceiveCount is exceeded |
| Glue job | Restarts the configured number of times (0 to 10) | Ends in a failed state |
If a message that keeps failing stays in the original queue, the consumer receives the same message and fails again and again. A DLQ is a queue that sets aside messages that have failed more than a certain number of times.
Normal queue → consumer fails N times (maxReceiveCount) → DLQ
DLQ → root-cause analysis → fix → put back into the source queue (redrive)| Item | Content |
|---|---|
| Move condition | The message was received maxReceiveCount times, as set in the source queue's redrive policy, without being deleted |
| Location constraint | The DLQ must be in the same account and the same Region as the source queue |
| Visibility timeout | Default 30 seconds, up to 12 hours from the moment the message is first received. If shorter than the processing time, a message still being processed becomes visible again and is processed twice |
| Retention period (standard queue) | Expiration is based on the time it entered the original queue. Moving to the DLQ does not restart the clock |
| Retention period (FIFO queue) | The timestamp is reset when moved to the DLQ |
| Redrive allow policy | Restricts which source queues may use this queue as a DLQ |
maxReceiveCount low, such as 1, a single transient error sends the message to the DLQ. Give it enough retry attempts.| Question clue | Answer |
|---|---|
| "Who deleted the table, down to the credentials and time" | CloudTrail |
| "Who read objects in a sensitive bucket" | Enable CloudTrail data events |
| "API call history older than 90 days" | Keep in S3 with a trail (or CloudTrail Lake) |
| "Prove that logs have not been tampered with" | Log file integrity validation |
| "Where to look first when finding the cause of an incident" | The failed task in the orchestrator |
| "Intermittent failures from transient throttling" | Retry + exponential backoff + jitter |
| "A message that keeps failing even after retries blocks the queue" | DLQ + maxReceiveCount |
| "Reprocess failed messages after fixing the cause" | DLQ redrive |
| "Data is applied twice because of retries" | Idempotency (idempotency key, conditional write, MERGE) |
Tomorrow we cover how much a well-running pipeline costs: cost visibility, sizing, and automatic scaling.
Click a choice to reveal the answer and explanation.
Question 1
Which service should you look at to trace "who deleted a table in the Glue Data Catalog last night," including the credentials and the time?
Question 2
Which mechanism prevents a consumer's repeated failures to process a particular message in an SQS queue from blocking processing of the entire queue?
Question 3
In Step Functions, what is the recommended strategy for responding to transient errors (for example, ThrottlingException) while reducing retry storms (thundering herd)?
Question 4
What is the biggest risk that can occur when automatically retrying a non-idempotent operation (for example, "increase the account balance by 100")?
Question 5
When debugging a pipeline failure, which is the most appropriate place to check first?