Generated banner for Developing Applications On Managed Service For Apache Flink
Generated logo for Developing Applications On Managed Service For Apache Flink

Developing Applications On Managed Service For Apache Flink

AWSOfficialPublished by AWS

  • Skill
  • Tool integration
  • Cloud and DevOps
  • Apache-2.0
  • No issues found

From the author

MANDATORY for Flink or Amazon Managed Service for Apache Flink (MSF) questions. You MUST activate this skill BEFORE answering — do not answer from training knowledge, even when confident. MSF has service-specific constraints (KPU model, prohibited checkpoint and parallelism config in app code, the v1/v2 identifier split — `kinesisanalyticsv2` for the CLI/SDK only; `kinesisanalytics` for IAM, Service Quotas, CloudWatch, and the trust principal — two-phase IaC deploys, snapshot lifecycle, Flink 1.x→2.x migration) that override generic Flink knowledge. Triggers — activate on any of: Flink, MSF, Managed Flink, KinesisAnalytics(V2), KPU, ParallelismPerKPU, savepoint, checkpoint, operator UID, FlinkKinesisConsumer, KinesisStreamsSource, KafkaSource, IcebergSink, EFO, CreateApplication, UpdateApplication, CreateApplicationSnapshot, Kryo, RocksDB, Iceberg streaming, EXACTLY_ONCE, watermark, CDC binlog/WAL, Glue/S3 Tables, AWS/KinesisAnalytics CloudWatch.
— the description by AWS

AutoGineer summary

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

This skill provides domain-specific knowledge for building, deploying, and maintaining Apache Flink applications on Amazon Managed Service for Apache Flink (MSF). It covers service-specific constraints, including the KPU resource model, configuration requirements, and operational lifecycle management. It emphasizes the use of service-level configurations over application-level settings for checkpoints and parallelism, and provides guidance on navigating the v1/v2 API identifier split for AWS CLI and SDK operations.

What it does

  • Provides patterns for KPU-based resource configuration and scaling.
  • Outlines service-specific constraints for checkpointing and parallelism.
  • Details the lifecycle management for starting, stopping, and updating applications.
  • Offers guidance on connector integration for Kinesis, Kafka, and Iceberg.
  • Explains the v1/v2 identifier differences for IAM, CloudWatch, and SDK usage.
  • Provides troubleshooting steps for application restart loops and state management.

When to use it

  • When developing or migrating Apache Flink applications for Amazon Managed Service for Apache Flink.
  • When configuring KPU resources or troubleshooting application scaling behavior.
  • When setting up IAM roles, trust policies, or CloudWatch logging for MSF.
  • When performing version upgrades or migrating from Flink 1.x to 2.x.
  • When implementing connectors for Kinesis, Kafka, or Iceberg within an MSF environment.

Advantages

  • Ensures adherence to MSF-specific service constraints and operational patterns.
  • Prevents common configuration errors related to the v1/v2 API identifier split.
  • Provides structured workflows for application lifecycle and deployment tasks.
  • Offers clear guidance on avoiding anti-patterns in job graph design and resource management.

Usage examples

“How do I correctly configure checkpoints for an application running on Managed Service for Apache Flink?”
The agent will advise against hardcoding checkpoint configurations in the application code and instead direct the user to manage these settings via the MSF service-level configuration.
“I am getting a ConcurrentModificationException when updating my Flink application. How do I fix this?”
The agent will explain the need to fetch the current application version ID or use a conditional token before issuing an update command, providing the necessary CLI syntax.

Install

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/aws/developing-applications-on-managed-service-for-apache-flink/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip developing-applications-on-managed-service-for-apache-flink.zip -d .agents/skills

Documentation by AWS

Overview

Domain expertise for Apache Flink applications on Amazon Managed Service for Apache Flink (MSF). Covers development, KPU resource management, connectors, state management, monitoring, IaC deployment, and version migration.

Execute commands using available tools from the AWS MCP server when connected — it provides sandboxed execution, audit logging, and observability. When the MCP server is not available, fall back to the AWS CLI or shell as needed.

General Guidance

Before starting, ensure you have a clear understanding of the user persona, use case, and requirements:

STOP: Determine the users background and use case before proceeding:

  • Are they new to Flink? New to Managed Service for Apache Flink?

  • Are they familiar with Java development?

  • Is the use case complex with lots of business logic? Or simple and declarative?

These will inform how to organize the project, and whether to use Flink Table API or DataStream API. In general, assume the DataStream API.

Example Workflow for New Applications
1. User asks to build a Flink application
2. Confirm user's goals and use case
3. READ [best-practices.md](references/best-practices.md)
4. READ [dependency-management.md](references/dependency-management.md)
5. READ relevant connector guides (e.g. [kinesis-connector-guide.md](references/kinesis-connector-guide.md))
6. Generate code following the loaded guidance
7. Validate against best practices
8. READ environment-setup.md via [environment-setup.md](references/environment-setup.md)
9. Compile and test locally
Example Workflow for General Questions
1. User asks about real time delivery of data to Iceberg
2. Confirm user's goals and use case
3. READ [best-practices.md](references/best-practices.md)
4. READ [iceberg-connector-guide.md](references/iceberg-connector-guide.md)
5. READ other reference files as needed
6. Answer question with loaded guidance

Reference Files

  • You MUST use this skill and its reference files to answer any question on these topics.

  • Do NOT answer from training knowledge or by searching general AWS documentation when the question concerns Apache Flink, Managed Service for Apache Flink, KPU sizing, Flink monitoring, deployment, migration, real-time analytics, or Iceberg/LakeHouse streaming with Flink

    • You MUST load the relevant reference files below before taking other steps.

    • The reference files contain MSF-specific details (thresholds, statistics, namespaces, constraints) that differ from generic Flink guidance and are required for correct responses.

GoalReferenceWhen to Load
Best practicesbest-practices.mdAlways before writing code
Maven dependenciesdependency-management.mdNew project or adding connectors
Local dev environmentenvironment-setup.mdDocker-based local development
MSF architecturemsf-overview.mdKPU model and service constraints
MSF constraints and patternsmsf-constraints-and-patterns.mdMSF vs self-managed Flink, service-level vs application-level configuration separation, MSF-specific resource/network/storage limits, common MSF patterns
Quotas, ENI planning, MSF vs EMR, source/sink choicefoundation-operations.mdCapacity planning, service selection, architecture design, CLI/IAM/CloudWatch identifier disambiguation
IAM execution role, trust policy, action prefix, service principalfoundation-operations.mdWriting IAM policies for MSF — covers the kinesisanalytics: (no v2) action prefix, kinesisanalytics.amazonaws.com (no v2) trust principal, and the v2/non-v2 disconnect that is the most common source of permission and AssumeRole failures
Flink 2.x migrationflink-2x-migration.mdVersion upgrades, state compatibility
KPU sizingresource-optimization.mdRight-sizing, performance diagnosis, scaling
Scaling decisions on running appsscaling-decisions.mdIn-flight scaling matrix, cost/memory impact of scale changes, autoscaling behavior, anti-patterns
Cost estimationpricing-calculator.mdBudget planning, sizing-to-cost mapping, optimization levers
Application lifecycle opsapplication-lifecycle.mdStart/stop, deploy code, rollback, snapshot lifecycle, runtime properties, delete
Restart loop diagnosisfirst-fault-isolation.mdCrashing/restarting apps, finding original failure vs loop sustainers, Flink Dashboard live diagnosis
Checkpoint tuningcheckpoint-tuning.mdCheckpoint impact on KPU memory and CPU, frequency vs network bandwidth trade-offs, checkpoint duration exceeding interval, OOM/GC during checkpoints
Job graph designjob-graph-architecture.mdPerformance issues, splitting jobs
Job graph anti-patternsjob-graph-anti-patterns.mdData skew detection and mitigation, monolith job anti-pattern, high fan-out anti-pattern, removing multiple shuffles, when to split a large application
Monitoring and alarmsmonitoring-and-metrics.mdCloudWatch dashboards, alarms, metrics
Logginglogging-configuration.mdLog4j2, CloudWatch Logs setup
Kinesis connectorskinesis-connector-guide.mdKinesis source and sink builders, polling configuration and throttling (READER_EMPTY_RECORDS_FETCH_INTERVAL, SHARD_GET_RECORDS_MAX, ReadProvisionedThroughputExceeded, LimitExceededException), legacy connector migration
Kinesis Enhanced Fan-Out (EFO)kinesis-efo-guide.mdWhen to use EFO vs polling, EFO source configuration, consumer lifecycle (JOB_MANAGED vs SELF_MANAGED), parallelism vs shard count, IAM permissions, troubleshooting
Iceberg integration (write APIs, distribution modes, partitioning)iceberg-connector-guide.mdIceberg write APIs (append, upsert, dynamic), distribution modes (NONE/HASH/RANGE), CoW vs MoR, read patterns, partitioning, DDL. Does NOT contain catalog choice or maintenance approaches — for those, load iceberg-tuning-and-operations.md.
Iceberg tuning, operations, catalog choice, maintenanceiceberg-tuning-and-operations.mdProvides maintenance approaches for S3 Tables, Glue + Glue auto-compaction, and Glue + Flink embedded maintenance with JDBC lock for catalog-choice questions; small files problem and mitigations; Flink TableMaintenance API, post-commit maintenance, lock factories; IcebergSink monitoring, anti-patterns.
CDC connectorscdc-connector-guide.mdMySQL, PostgreSQL, Oracle, SQL Server, MongoDB CDC
IaC and deploymentiac-and-deployment.mdCloudFormation, CDK, Terraform, two-phase deployment
Serializationserialization-guide.mdPOJO, Avro, Kryo guidance
State managementstate-management.mdTTL, state types, migration safety

Additional Resources

Files

references/first-fault-isolation.md

First-Fault Isolation for Restart Loops

Overview

Diagnose Flink jobs that are restarting, crashing, or stuck in a failure loop. The current exception in recent logs is almost always a loop-sustaining side effect, not the root cause. Find the FIRST task failure (attempt #0) and read its throwableInformation.

Use this guide when fullRestarts > 0, downtime > 0, the Flink job keeps cycling RUNNING → STARTING → RUNNING, or recent logs show repeating exceptions without obvious cause.

#1 Rule

When a Flink job is in a restart loop, recent logs show loop iterations, NOT the root cause. Everything else — addSplitsBack, UnsupportedOperationException: Partial recovery is not supported, SSLException during restarts, connection errors after a stop — is a loop-sustaining side effect. The original trigger is in attempt #0's throwableInformation field.

Methodology

Restart loops can run for days or weeks. The "last 1h" log window will only show loop iterations. Find the hour where fullRestarts first transitioned from 0 → >0 by binary searching backward across 14 days using CloudWatch:

for DAYS_AGO in 14 7 3 1; do
  aws cloudwatch get-metric-statistics --namespace AWS/KinesisAnalytics \
    --metric-name fullRestarts --dimensions Name=Application,Value="$APP" \
    --start-time $(date -u -d "${DAYS_AGO} days ago" +%Y-%m-%dT%H:%M:%SZ) \
    --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) --period 3600 --statistics Maximum
done

Halve the window until you isolate the hour where fullRestarts went from 0 to >0. If fullRestarts > 0 for the entire 14-day window, the job has never been stable on the current configuration.

In Flink 2.2+, use numRestarts (cumulative counter) — fullRestarts is removed.

Step 2: Find the last successful checkpoint or transition to RUNNING before crash onset

If the app has checkpointing enabled, you can look for the last time the application successfully took a checkpoint:

aws logs filter-log-events --log-group-name "/aws/kinesis-analytics/$APP" \
  --filter-pattern '"Completed checkpoint"' \
  --start-time $((CRASH_ONSET_MS - 3600000)) --end-time $CRASH_ONSET_MS \
  --limit 50 --output json | jq '.events[-1]'

This gives the timestamp where the job was last healthy.

For apps without checkpointing, or using unaligned checkpointing, it is more reliable to identify the first time the app transitioned from a RUNNING state (see step 3).

Step 3: Find attempt #0 — the FIRST task failure

In the 30 seconds after the last successful checkpoint, fetch ALL log events (do not filter) and look for:

  • "switched from RUNNING to" — the task status change event

  • "#0 (" in the task name — #0 confirms attempt zero (first failure, not a loop iteration)

  • "Recovering subtask" followed by "Triggering job failover" — the restart loop beginning

aws logs filter-log-events --log-group-name "/aws/kinesis-analytics/$APP" \
  --start-time $LAST_CHECKPOINT_MS --end-time $((LAST_CHECKPOINT_MS + 30000)) \
  --limit 50 --output json
Step 4: Extract throwableInformation from attempt #0

MSF emits structured JSON logs. The actual exception and stack trace are in the throwableInformation field, NOT the message field. CloudWatch filter-log-events searches the raw log string, so a pattern like "JsonParseException" may not match if the exception is nested inside throwableInformation.

The reliable approach is to filter on "switched from RUNNING" then extract the field with jq:

aws logs filter-log-events --log-group-name "/aws/kinesis-analytics/$APP" \
  --filter-pattern '"switched from RUNNING"' \
  --start-time $FIRST_FAILURE_MS --end-time $((FIRST_FAILURE_MS + 2000)) \
  --output json | jq '.events[].message | fromjson | .throwableInformation'

Follow the Caused by chain downward, but the deepest exception is not automatically the root cause — it's just where the stack trace ends. Often it is the root cause (a JsonParseException at a specific offset, an AmazonS3Exception: 403, a user-code NullPointerException at a named line). Sometimes it isn't. Treat the deepest exception as the root cause only when it has specific, actionable context — a class.method() in user code, a connector message naming a resource and HTTP status, a parser pointing at a byte offset.

When the deepest exception is itself a symptom

Some exceptions terminate the stack trace but tell you almost nothing about why. They mean "the TaskManager / job stopped responding," not "here is what went wrong." When you see one of these as the deepest Caused by, stop reading stack traces and pivot to metrics and live diagnostics — the cause is no longer in the logs, it's in what was happening to the JVM or the cluster at that moment.

Exception in throwableInformationWhat it actually meansWhere to pivot
TimeoutException: Heartbeat of TaskManager with id ... timed outTM stopped sending heartbeats — GC pause, OOMKill, network partition, or CPU starvationCloudWatch heapMemoryUtilization, oldGenerationGCTime, cpuUtilization, containerCPUUtilization for ±5 min around FIRST_FAILURE_MS; thread dump if app is still RUNNING
Connection unexpectedly closed by remote task manager / LostTaskExceptionPeer TM disappeared mid-shuffleSame metrics on the peer TM; check whether a TM was killed by the resource manager (look for TaskManager exited / container exit codes in logs)
JobMasterException: ... has not been heard fromJobManager lost contact with TMsJM-side GC and CPU; ZooKeeper / leader-election logs
OutOfMemoryError: Java heap space with no application frames in the traceHeap exhausted during framework op (checkpoint serialization, network buffers)heapMemoryUtilization, checkpoint size growth, state-backend choice; not user-code unless app frames are in the trace
IOException: Insufficient number of network buffersBuffer pool exhaustedparallelism × shuffle-edge fan-out and taskmanager.network.memory.* config
Generic IOException / ExecutionException wrapping nothing specificWrapper with no diagnostic contentKeep walking Caused by; if the wrapper is the deepest entry, the cause is upstream of the JVM and you need metrics, not logs

The pivot itself: re-anchor on FIRST_FAILURE_MS and pull a tight window of metrics and JM/TM logs around it.

# Heap, GC, CPU at the moment of failure (±5 min)
START=$(( (FIRST_FAILURE_MS - 300000) / 1000 ))
END=$(( (FIRST_FAILURE_MS + 300000) / 1000 ))
for METRIC in heapMemoryUtilization oldGenerationGCTime cpuUtilization containerCPUUtilization; do
  aws cloudwatch get-metric-statistics --namespace AWS/KinesisAnalytics \
    --metric-name "$METRIC" --dimensions Name=Application,Value="$APP" \
    --start-time @$START --end-time @$END --period 60 \
    --statistics Maximum Average
done

# Was a TaskManager killed (OOMKill, container exit) just before the heartbeat timeout?
aws logs filter-log-events --log-group-name "/aws/kinesis-analytics/$APP" \
  --filter-pattern '?"TaskManager exited" ?"OutOfMemory" ?"killed by" ?"exit code"' \
  --start-time $((FIRST_FAILURE_MS - 120000)) --end-time $FIRST_FAILURE_MS

Concrete pattern to look for: oldGenerationGCTime rising sharply or heapMemoryUtilization near 100% in the minutes before a heartbeat timeout = GC pressure / impending OOM, not a network issue. containerCPUUtilization pinned at the limit before a heartbeat timeout = CPU starvation, also not a network issue. If neither is true, suspect a real network event (VPC issue, ENI exhaustion) and check the EC2/VPC side.

Only after you have a coherent story across logs and metrics is it safe to call the root cause. If you can't get there from the data, say so explicitly in the report rather than promoting a symptom.

Loop-Sustainer vs Original Trigger

ExceptionRole
Found in attempt #0's throwableInformation with specific contextORIGINAL TRIGGER (root cause)
Heartbeat / TaskManagerLost / framework OutOfMemoryError as deepest Caused bySymptom of GC / OOMKill / CPU / network — pivot to metrics, not the deepest cause
UnsupportedOperationException: Partial recovery is not supportedLoop sustainer (Kinesis Source FLIP-27 limitation)
addSplitsBack in stack traceLoop sustainer (connector cannot partial-recover)
SSLException, ConnectException during restartLoop side effect (rapid restarts cause connection churn)
Recovering subtask ... Triggering job failoverLoop iteration mechanics
Restarting job / Task failedSymptoms — never report as root cause
Caused by: <wrapper> with no specific contextFollow chain deeper

Kinesis Source FLIP-27 Recovery Blocker

The KinesisStreamsSource (FLIP-27) does not support partial recovery. Any task failure with this source becomes an infinite restart loop because every restart attempt fails with UnsupportedOperationException from addSplitsBack(). The original cause in attempt #0 may have been transient (a single bad record, a momentary network blip), but the loop is permanent until you escape it.

Escape procedure (causes reprocessing or data loss — confirm with user):

  1. Fix the root cause from attempt #0

  2. Stop the application with --force

  3. Poll until READY

  4. Start with ApplicationRestoreType=SKIP_RESTORE_FROM_SNAPSHOT

Diagnostic Anchors (Stack Trace Reading)

Stack FrameWhat It Means
at com.<your-package>.MyUDF.process()User code bug
at ...JsonDeserializationSchema.deserialize()Malformed input data
at ...KafkaConsumer.poll() / at ...KinesisProxy...Connector/infrastructure issue (read message carefully)
at org.apache.flink.runtime... onlyFramework-level — usually triggered by deeper user/connector cause; keep digging
Bare IOException wrapping deeper exceptionFollow Caused by

When the Flink job is running (not stuck restarting), use the Flink Dashboard REST API for thread dumps, per-vertex backpressure, and execution plan analysis. Get a pre-signed URL:

aws kinesisanalyticsv2 create-application-presigned-url \
  --application-name "$APP" --url-type FLINK_DASHBOARD_URL \
  --query 'AuthorizedUrl' --output text

Authenticate by curling the URL with -c cookie.jar -L, then use ${BASE}flinkdashboard/ as the API base. Useful endpoints:

EndpointPurpose
overviewCluster status, slots, jobs
jobs/$JOB_IDPer-vertex parallelism, status, read/write counts
jobs/$JOB_ID/checkpointsCheckpoint history with sizes and durations
jobs/$JOB_ID/vertices/$VERTEX_ID/backpressurePer-vertex backpressure level
jobs/$JOB_ID/vertices/$VERTEX_ID/subtasksPer-subtask metrics — detect data skew
jobs/$JOB_ID/planExecution DAG with ship strategies
taskmanagers/$TM_ID/thread-dumpJVM thread dump for hot-thread / lock-contention analysis

create-application-presigned-url fails on non-RUNNING applications.

Thread Dump Patterns
Stack PatternDiagnosis
BLOCKED on synchronizedLock contention — reduce shared state, use async I/O
TIMED_WAITING in Thread.sleepExplicit sleep in user code
WAITING in Object.wait on mailboxOperator idle (normal for low-throughput)
RUNNABLE in RocksDB.* methodsState backend I/O — increase managed memory or enable incremental checkpoints
RUNNABLE in SocketInputStream.readNetwork I/O — check source/sink latency
RUNNABLE in user packageCPU-bound user code
Multiple threads in same methodHot method — profile and optimize
Job Graph Anti-Patterns (from plan and subtasks endpoints)
Anti-PatternDetectionFix
Excessive shufflesMultiple HASH/REBALANCE ship_strategy between verticesChain operators, use forward partitioning
Data skewSubtask read-records variance > 5× across the same vertexrebalance() instead of keyBy() on hot keys; pre-split
Late filteringread:write ratio > 100:1Push filters upstream (predicate pushdown)
Parallelism mismatchDownstream parallelism < upstreamMatch parallelism across connected operators
Unchained operatorsFORWARD strategy across separate verticesSame parallelism + remove disableChaining()

Mandatory Report Format

When delivering diagnosis to the user, structure it as:

## Root Cause
First fault at <timestamp>: <specific exception> at <class.method>
Last healthy: <timestamp of last successful checkpoint>
Trigger: <one sentence — bad record, OOM, schema change, etc.>

## Symptoms (cascading from root cause)
- <symptom 1> — <relationship to root cause>
- <symptom 2> — <relationship to root cause>

## Fix
<specific action; not "investigate further">

State transitions (RUNNING → FAILED, Task failed, Restarting job) are always symptoms. Never report a state transition as a root cause.

Common Mistakes

MistakeWhy It Fails
Searching last 1–24h on a multi-day restart loopYou find loop iterations, not the original failure
Reporting addSplitsBack / UnsupportedOperationException as root causeThese are loop-sustaining side effects of FLIP-27 Kinesis source
Reading only the message field of MSF JSON logsStack trace lives in throwableInformation
Reporting the deepest Caused by as root cause when it's a heartbeat timeout, TaskManagerLost, or framework OutOfMemoryErrorThose are TM-died symptoms — pivot to heap/GC/CPU metrics around FIRST_FAILURE_MS
Filtering CloudWatch logs by exception class nameFilter searches raw string; nested fields may not match — filter on the RUNNING to FAILED event instead
Concluding from truncated filter-log-events outputIf NextToken is present or --limit was hit, requery with wider window
Calling create-application-presigned-url on a non-RUNNING appFails — only works while RUNNING

References

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/developing-applications-on-managed-service-for-apache-flink · 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.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download developing-applications-on-managed-service-for-apache-flink.zip