Skip to content

Stateless Flink State Snapshot#1079

Open
Yanisdje wants to merge 15 commits into
apache:mainfrom
Shopify:yd/state-snapshot-fix
Open

Stateless Flink State Snapshot#1079
Yanisdje wants to merge 15 commits into
apache:mainfrom
Shopify:yd/state-snapshot-fix

Conversation

@Yanisdje

Copy link
Copy Markdown

Problem

When a FlinkStateSnapshot CR is deleted before the FlinkStateSnapshotController has reconciled it, the cleanup() method throws a NullPointerException on getStatus().getState(). The exception is caught in a way that prevents the finalizer from being removed, causing the CR to be permanently stuck in a terminating state. This blocks namespace deletion.

Root Cause

FlinkStateSnapshotController.cleanup() and FlinkResourceContextFactory.getFlinkStateSnapshotContext() assume the status is non-null, but FlinkStateSnapshot CRs are created without a status (the status subresource is only populated when reconcile() runs). If the CR receives a deletion timestamp before reconcile() runs, JOSDK calls cleanup() directly — the only code path that initializes null status is in reconcile(), not cleanup().

The NPE propagates to JOSDK (or is caught by the controller's catch block returning noFinalizerRemoval()), causing an infinite retry loop where every attempt crashes the same way.

reconcile() already handles this case correctly:

// status might be null here
flinkStateSnapshot.setStatus(
        Objects.requireNonNullElseGet(
                flinkStateSnapshot.getStatus(), FlinkStateSnapshotStatus::new));

cleanup() and updateErrorStatus() are missing this guard.

Impact

  • FlinkStateSnapshot CRs with null status accumulate as zombie resources with finalizers that can never be cleared.
  • Namespace deletion is blocked indefinitely

Fix

Add the same null-status initialization to cleanup() and updateErrorStatus() that already exists in reconcile(). A null-status snapshot was never triggered against Flink, so no data exists on storage and cleanup can safely proceed

@Yanisdje Yanisdje force-pushed the yd/state-snapshot-fix branch from 1062465 to 21867b8 Compare March 30, 2026 17:40
Comment on lines +166 to +171
var result =
startTransition(
context,
currentBlueGreenDeploymentType,
currentFlinkDeployment);
// Only stamp lastReconciledSpec after the transition

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change related?

@vsantwana

Copy link
Copy Markdown
Contributor

Hello @Yanisdje
Can I please request you to add the JIRA ticket number on the PR so that it shows up on the FLINK JIRA here and also possibly get the ticket assigned to yourself before creating a PR (This is also highlighted in the contribution guide)
Asking because it allows other contributors to know the accurate state of the ticket and avoids duplicate work/interest.
Thanks!

@gyfora

gyfora commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

@Yanisdje are you still working on this? :)

@nihar4276

Copy link
Copy Markdown

@Yanisdje @gyfora We hit this bug at Bloomberg with flink kubernetes operator 1.14.0. If Yanisdje is unavailable, I can make a quick PR. Let me know, thanks

@gyfora

gyfora commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

Thanks @nihar4276 that would be great. I think you can for the existing work on this PR to help wrap it up and remove anything unnecessary :)

@Yanisdje

Copy link
Copy Markdown
Author

Hello @gyfora and @nihar4276!

Apologies for the delayed response, it seems that I was receiving the notifications in the wrong email. I could get back to it tomorrow, will keep folks updated.

Thanks!

@nihar4276

Copy link
Copy Markdown

Nice to meet you both 💯 . I will let Yanis take this PR to the finish line, and feel free to ping me if you need help. Thanks :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants