Generated banner for Debugging Mwaa Workflow
Generated logo for Debugging Mwaa Workflow

Debugging Mwaa Workflow

AWSOfficialPublished by AWS

  • Skill
  • Review and audit
  • Cloud and DevOps
  • Apache-2.0
  • No issues found

From the author

Diagnoses and root-causes Amazon MWAA workflow failures across Provisioned (Python DAG) and Serverless (YAML workflow) environments. Provisioned uses aws mwaa invoke-rest-api, CloudWatch log groups, and get-environment; Serverless uses aws mwaa-serverless API (GetWorkflowRun, ListWorkflowRuns, GetTaskInstance) and CloudWatch logs. Covers failed runs and tasks, DAGs not appearing, import errors, worker OOM, IAM denials, and dependency drift. Triggers on: DAG failed, task failed, workflow run failed, MWAA error, debug my DAG, why did my workflow fail, DAG not showing up, MWAA import error, requirements failing, worker crashed, serverless run failed. Not applicable to authoring workflows (handled by authoring-mwaa-workflow), running or smoke-testing a workflow (handled by testing-mwaa-workflow), or CI-CD deploy failures.
— the description by AWS

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

This skill provides a systematic, read-only diagnostic framework for troubleshooting Amazon Managed Workflows for Apache Airflow (MWAA). It handles both Provisioned (Python DAG) and Serverless (YAML) environments by routing failures through a standardized 4-step process: detection, identification, categorization, and context analysis. It leverages AWS CLI commands to query MWAA APIs and CloudWatch logs, providing actionable root cause analysis, impact assessments, and remediation recommendations while maintaining production safety by never executing state-mutating commands autonomously.

What it does

  • Detects and categorizes MWAA workflow failures including task crashes, import errors, and IAM denials.
  • Queries MWAA Provisioned environments via invoke-rest-api and CloudWatch logs.
  • Analyzes MWAA Serverless workflows using GetWorkflowRun and task instance logs.
  • Provides a structured diagnostic report with root cause, impact, and remediation steps.
  • Offers specific troubleshooting checklists for common issues like DAGs not appearing in the UI.
  • Maintains security by performing only read-only operations and suggesting safe remediation commands.

When to use it

  • When a DAG or task fails unexpectedly in an MWAA environment.
  • When a DAG is not appearing in the Airflow UI.
  • When diagnosing worker OOM (SIGKILL) or dependency drift issues.
  • When investigating 'AccessDenied' or 'EntityNotFound' errors in workflow logs.
  • When needing to distinguish between definition errors and task-execution failures.

Advantages

  • Standardizes the diagnostic process across different MWAA deployment models.
  • Prioritizes safe, read-only investigation to prevent accidental production changes.
  • Provides clear, actionable remediation paths for complex issues like dependency drift.
  • Reduces manual log-diving by automating the retrieval of relevant error details.
  • Includes specific guidance for common, non-obvious issues like scheduler scan intervals.

Usage examples

“Why did my workflow fail?”
The agent will identify the environment flavor, list recent failed runs, pull the relevant error logs, and provide a structured report with the root cause and remediation steps.
“My DAG is not showing up in the UI, help me debug.”
The agent will walk through the DAG registration checklist, checking for import errors, scan intervals, dag_id collisions, and S3-sync delays.
“Why is my worker crashing with a SIGKILL?”
The agent will analyze the worker logs, confirm the environment class and memory constraints, and recommend moving heavy tasks to external services like Glue or EMR.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/aws/debugging-mwaa-workflow/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip debugging-mwaa-workflow.zip -d .agents/skills

Documentation by AWS

Debugging MWAA Workflows

AWS MCP server (optional but recommended): running the AWS CLI commands in this skill through the AWS MCP server gives sandboxed execution and audit logging. Every command here also works with the plain AWS CLI, so the skill does not require the MCP server or any MCP-only tools.

Diagnose and root-cause Amazon MWAA workflow failures, then report root cause, impact, and recommended remediation. Routes by flavor, then runs a shared 4-step diagnostic spine.

Guardrail — where this skill's own files live (MCP vs local install)

This skill can be loaded two ways, and they resolve the skill's own bundled files from different places. Determine how the skill was loaded before reading a reference:

  • Loaded through the AWS MCP retrieve_skill tool: The skill is not installed on the local filesystem. You MUST fetch each reference via retrieve_skill with the file parameter (e.g. file="references/failure-catalog.md") and read the returned content. Do NOT file_read these paths locally — they do not exist on disk.

  • Installed locally (e.g. .kiro/skills/debugging-mwaa-workflow/ or ~/.claude/skills/debugging-mwaa-workflow/): Read the files from the local skill directory using relative paths.

This distinction applies only to the skill's own packaged files. User data and session artifacts are always read from and written to the user's working directory. Never fetch or write customer data through retrieve_skill.

Step 0: Detect Flavor and Scope the Failure

Detect flavor
  1. An environment name resolvable via aws mwaa get-environment means the environment is Provisioned.

  2. A workflow/... ARN or any aws mwaa-serverless context means the environment is Serverless. A bare run identifier does NOT indicate flavor — Provisioned DAG runs also have run ids.

  3. If neither signal is present, ask: is the target MWAA Provisioned (Python DAG) or MWAA Serverless (YAML workflow)?

Route by complexity
  • Simple — a single named task or run failed with a clear exception. Jump to Step 2 for that task.

  • Standard — a run failed and the cause is unknown. Run the full Step 1 to Step 4 sweep.

  • Complex — intermittent or environment-wide (multiple DAGs, "worked yesterday", nothing appearing). Run the full sweep with emphasis on Step 3.

Step 1: Identify the Failure

Provisioned: list failed DAG runs and task instances via aws mwaa invoke-rest-api (paths /dags/{id}/dagRuns and /dags/{id}/dagRuns/{run_id}/taskInstances). If invoke-rest-api errors (RestApiClientException), fall back to the Scheduler and DAGProcessing log groups. Get version and config from aws mwaa get-environment. See references/provisioned-diagnostics.md.

Serverless: aws mwaa-serverless list-workflow-runs, then get-workflow-run. Read RunDetail.ErrorMessage — an empty TaskInstances with a parser message is a definition error; Workflow execution failed with populated TaskInstances is a task-execution failure. See references/serverless-diagnostics.md.

Step 2: Get Error Details and Categorize

Pull the real exception past boilerplate:

Provisioned: read the Task log group first, then Worker/Scheduler/ DAGProcessing as the symptom directs.

Serverless: list-task-instances then get-task-instance to get each task's LogStream, then read that stream in CloudWatch.

Then categorize in priority order — infra, then drift, then code-data — using references/failure-catalog.md. The category determines the Step 3 checks.

Step 3: Check Context (Why It Happened)

Run the context checks for the matched category from references/failure-catalog.md. Do not stop at the surface exception: a SIGKILL is an OOM story, a fresh import error on unchanged code is a drift story, a sensor timeout is an upstream-health story.

Step 4: Provide Actionable Output

Report in this exact structure:

Root Cause: <one-line diagnosis with the evidence that proves it>
Impact: <what failed, which runs, blast radius>
Immediate Fix: <the smallest change that unblocks>
Prevention: <the change that stops recurrence>
Commands: <exact read-only commands run, plus remediation commands for the user to run>

Run only read-only operations. Present state-mutating remediation (clear/rerun/backfill for Provisioned; start-workflow-run or fix-and-redeploy for Serverless) as commands for the user to run, with the impact stated. Never execute them autonomously (production safety).

For the fix-and-redeploy path, use authoring-mwaa-workflow to regenerate a compliant artifact.

Gotchas

  • Serverless has no Airflow web UI, no REST API, and no CLI token. Do not attempt create-web-login-token, invoke-rest-api, or any Airflow REST path for Serverless.

  • For Provisioned, always use aws mwaa invoke-rest-api (not create-web-login-token + curl). invoke-rest-api reaches VPC-only web servers without network access.

  • GetWorkflowRun.RunDetail.ErrorMessage distinguishes a definition error (empty TaskInstances) from a task-execution failure (Workflow execution failed, populated TaskInstances). Read it before pulling task logs.

  • The Serverless log group defaults to /aws/mwaa-serverless/{workflow-id}/ but can be a custom group; confirm via get-workflow LoggingConfiguration before assuming the path.

  • A DAG not appearing has several causes — an import/parse error, the scheduler scan interval (scheduler.dag_dir_list_interval, or dag_processor.refresh_interval on Airflow 3.x) not yet elapsed, a dag_id collision, or S3-sync delay — and is rarely a broken DAG. Check GET /importErrors and GET /dags/{dag_id} via invoke-rest-api (and the DAGProcessing logs); see the failure catalog's "DAG not appearing in the UI" checklist before concluding the code is wrong.

  • A worker SIGKILL is an OOM signal. Recommend moving work to Glue/EMR/Lambda; scaling workers alone does not fix per-task memory pressure.

  • MWAA re-resolves dependencies on environment update, so an unchanged DAG can start failing on import with no code change. Treat no-code-change import failures as drift.

  • Serverless PythonOperator/BashOperator tasks run custom code from a --code package. A run that fails to extract the package or hits ModuleNotFoundError is a packaging problem (wrong-platform wheel, missing dep, bad layout), not a YAML definition error. See the failure catalog's serverless custom-code section.

Troubleshooting

ErrorCauseFix
RestApiClientException (Provisioned)Mis-scoped execution role or service errorFall back to Scheduler/DAGProcessing log groups
ResourceNotFoundException on get-workflow-runWrong workflow ARN or run idRe-list with list-workflow-runs
Task log stream empty (Serverless)Wrong log group assumedRead LoggingConfiguration from get-workflow
No task logs but run FAILEDDefinition/parse errorRead RunDetail.ErrorMessage; fix the YAML

References

Security Considerations

  • Read-only by default: diagnosis uses only read/list/describe calls. Remediation (clear/rerun/backfill, IAM or key-policy changes) is presented as commands for the user to run, never executed autonomously.

  • Least-privilege IAM: when an AccessDenied is a genuine permission gap, recommend the minimal Action/Resource from the error — never a wildcard; distinguish it from a nonexistent-resource typo (do not broaden IAM then).

  • Cross-account: KMS key-policy / assume-role changes are human-gated and coordinated with the resource owner.

  • No secret exposure: do not surface credentials or connection strings from logs or API responses in the diagnosis output.

Files

references/provisioned-diagnostics.md

Provisioned MWAA Diagnostics

Data sources for MWAA Provisioned (Python DAG) failure investigation. All investigation operations are read-only; the remediation commands at the end change state and are for the user to run.

Environment facts (always start here)

  • aws mwaa get-environment --name <env> returns Airflow version, environment class, LoggingConfiguration (which CloudWatch log groups are enabled and at what level), AirflowConfigurationOptions, MinWorkers/MaxWorkers, execution role ARN, and S3 SourceBucketArn / DagS3Path / RequirementsS3Path / PluginsS3Path.

  • aws mwaa list-environments resolves the environment name when the user is vague.

CloudWatch component log groups (primary log source)

MWAA delegates all logging to CloudWatch. The Airflow REST API task-instance logs endpoint (/taskInstances/{id}/{try}/logs) is unreliable — it may return empty content or an error. Always fetch task log content directly from CloudWatch using aws logs filter-log-events with the Task log group and a filter pattern matching the task ID or DAG run ID.

LoggingConfiguration in get-environment gives the exact log group ARNs. Component-to-symptom mapping:

ComponentLog group suffixRead when
DAGProcessing-DAGProcessingDAG not appearing, import errors
Scheduler-Schedulerrun never started, scheduling gaps
Task-Taska task failed; the real exception is here
Worker-WorkerSIGKILL/OOM, task stuck, autoscaling
WebServer-WebServerUI 5xx, login failures

Read logs with aws logs filter-log-events --log-group-name <name> --start-time <ms> or the CloudWatch Logs MCP tool if available.

Airflow REST API via invoke-rest-api (run and task state)

All Airflow REST API calls use aws mwaa invoke-rest-api — a single AWS API call that proxies the request through the MWAA control plane. No create-web-login-token, no curl, no session exchange. invoke-rest-api reaches private (VPC-only) web servers that are otherwise inaccessible.

invoke-rest-api returns {"RestApiStatusCode": <int>, "RestApiResponse": {...}}. Read the run/task state from RestApiResponse.

List failed DAG runs
aws mwaa invoke-rest-api --name <env> --path /dags/<dag_id>/dagRuns \
  --method GET --query-parameters '{"order_by": "-start_date", "limit": "5"}'

Read RestApiResponse.dag_runs[].state. Filter for failed.

Get task instances for a failed run

Use the collection endpoint and pass the run in query parameters — the --path is capped at 64 characters (MWAA InvokeRestApi), and the per-run path below often exceeds it:

aws mwaa invoke-rest-api --name <env> \
  --path /dags/<dag_id>/taskInstances --method GET \
  --query-parameters '{"dag_run_id":"<run_id>","limit":"100","offset":"0"}'

The per-run path is shorter to read but embeds <run_id> in the path, so /dags/<dag_id>/dagRuns/<run_id>/taskInstances frequently exceeds the 64-char limit and is rejected with an opaque RestApiClientException; use it only when the fully-substituted path stays under 64 characters:

aws mwaa invoke-rest-api --name <env> \
  --path /dags/<dag_id>/dagRuns/<run_id>/taskInstances --method GET

Read RestApiResponse.task_instances[].state. Failed tasks carry the exception in their Task log group (see above). Both forms paginate (Airflow REST default limit 100): a run using dynamic task mapping (.expand()) can have more than 100 task instances, so re-issue with offset incremented by 100 until you have read total_entries — otherwise failed mapped tasks beyond the first 100 are missed.

Check DAG registration / parse state (a DAG not appearing)
# Import/parse errors across all files (traceback + filename); paginated
# (default limit 100) — loop offset until total_entries when a shared module
# breaks many files
aws mwaa invoke-rest-api --name <env> --path /importErrors --method GET \
  --query-parameters '{"limit":"100","offset":"0"}'

# Registration state of one DAG: last_parsed_time, fileloc, is_active (2.x) / is_stale (3.x)
aws mwaa invoke-rest-api --name <env> --path /dags/<dag_id> --method GET

Read RestApiResponse. A file listed under /importErrors failed to parse — fix the code and it re-registers on the next scan. If GET /dags/<dag_id> returns 404 the DAG has not registered yet: wait one scheduler.dag_dir_list_interval (Airflow 2.x) / dag_processor.refresh_interval (Airflow 3.x) scan cycle, or check for a duplicate dag_id. last_parsed_time and fileloc (both 2.x and 3.x) confirm it parsed and which file won a dag_id collision; read is_active on Airflow 2.x, or is_stale (inverted) on Airflow 3.x, and has_import_errors for a parse failure.

Fallback

A RestApiClientException (rare — possible on a mis-scoped execution role) means invoke-rest-api cannot reach the web server. Fall back to the Scheduler and DAGProcessing CloudWatch log groups for run/task state.

Remediation commands (present to user; do not execute)

  • Clear and rerun a task:

    aws mwaa invoke-rest-api --name <env> \
      --path /dags/<dag_id>/clearTaskInstances --method POST \
      --body '{"dry_run": false, "task_ids": ["<task_id>"], "dag_run_id": "<run_id>"}'
  • Trigger a new run (body differs by Airflow major):

    # Airflow 3.x (REST v2): logical_date, NO top-level conf
    aws mwaa invoke-rest-api --name <env> --path /dags/<dag_id>/dagRuns \
      --method POST --body '{"dag_run_id": "<explicit-id>", "logical_date": "<unique-ISO8601-UTC>"}'
    # Airflow 2.x (REST v1): conf accepted, logical_date not required
    aws mwaa invoke-rest-api --name <env> --path /dags/<dag_id>/dagRuns \
      --method POST --body '{"dag_run_id": "<explicit-id>", "conf": {}}'
  • Backfill: run airflow dags backfill through the MWAA CLI token endpoint (aws mwaa create-cli-token).

These change environment state. Present the exact command and its impact; let the user run it (production safety).

Requirements and compatibility

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Needs an MCP server

Security

No issues found by our static scan· No issues found

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
AWS
Publisher
AWS (Official)
Source
aws/agent-toolkit-for-aws · plugins/aws-data-analytics/skills/debugging-mwaa-workflow · commit 0a218f8
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • NOTICE (added by AutoGineer from NOTICE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced
Also distributed in
aws/agent-toolkit-for-aws

AutoGineer is not affiliated with or endorsed by AWS or AWS.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download debugging-mwaa-workflow.zip