<a id="release-notes"></a>

# Confluent for Kubernetes Release Notes

<style>
.rss-feed-box {
    /\* --cf-surface-01 is white in light mode and a neutral dark surface in
       dark mode (see confluent.css), so unlike a raw palette color this
       needs no explicit [data-theme="dark"] override to read correctly in
       both themes. \*/
    background-color: var(--cf-surface-01);
    border: 1px solid var(--cf-border-subtle);
    border-radius: var(--cf-radius-md);
    padding: 16px 20px;
    margin: 20px 0;
    display: flex;
    align-items: flex-start;
    gap: 16px;
}
.rss-icon {
    width: 24px;
    height: 24px;
    background-color: var(--color-orange-40);
    border-radius: var(--cf-radius-sm);
    display: flex;
    align-items: flex-start;
    justify-content: flex-start;
    flex-shrink: 0;
    transform: rotate(90deg);
}
.rss-icon svg {
    width: 24px;
    height: 24px;
    fill: var(--cf-text-on-color);
}
.rss-feed-rest {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.rss-content {
    color: var(--cf-text-primary);
    font-size: 14px;
    line-height: 1.5;
}
.rss-feed-url-container {
    display: flex;
    align-items: center;
    gap: 8px;
    /\* Explicit hex/palette pair (not a semantic --cf-\* token) because the
       code-block shade here is intentionally lighter/darker than
       --cf-surface-01 above, to read as a distinct "code" region nested
       inside the neutral box. Raw palette tokens don't flip with the theme
       on their own - same explicit [data-theme="dark"] override
       confluent.css uses for its .rst-content note/tip admonitions. \*/
    background-color: var(--color-neutral-10);
    border-radius: var(--cf-radius-sm);
    padding: 10px 14px;
}
[data-theme="dark"] .rss-feed-url-container {
    background-color: var(--color-neutral-80);
}
.rss-feed-url {
    font-family: var(--cf-font-family-mono);
    font-size: 13px;
    color: var(--cf-text-primary);
    word-break: break-all;
    flex: 1;
}
.copy-button {
    background-color: transparent;
    border: none;
    border-radius: var(--cf-radius-sm);
    color: var(--cf-interactive-input);
    cursor: pointer;
    padding: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    transition: background-color 0.2s ease, color 0.2s ease;
}
.copy-button:hover {
    background-color: var(--cf-border-subtle);
}
.copy-button:active {
    transform: scale(0.92);
}
.copy-button.copied {
    color: var(--cf-support-success);
}
.copy-icon {
    width: 16px;
    height: 16px;
    fill: currentColor;
}
.copy-button .icon-check {
    display: none;
}
.copy-button.copied .icon-copy {
    display: none;
}
.copy-button.copied .icon-check {
    display: block;
}
.external-link-icon {
    display: inline-block;
    width: 12px;
    height: 12px;
    margin-left: 4px;
    vertical-align: middle;
}
.rss-sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}
</style>

<div class="rss-feed-box">
   <div class="rss-icon"><svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"><path d="M200-120q-33 0-56.5-23.5T120-200q0-33 23.5-56.5T200-280q33 0 56.5 23.5T280-200q0 33-23.5 56.5T200-120Zm480 0q0-117-44-218.5T516-516q-76-76-177.5-120T120-680v-120q142 0 265 53t216 146q93 93 146 216t53 265H680Zm-240 0q0-67-25-124.5T346-346q-44-44-101.5-69T120-440v-120q92 0 171.5 34.5T431-431q60 60 94.5 139.5T560-120H440Z"/></svg></div>
   <div class="rss-feed-rest">
        <div class="rss-content">
            To get the latest product updates delivered to you in an RSS feed, add the URL of this page to your <a href="https://en.wikipedia.org/wiki/News_aggregator" target="_blank" rel="noopener">feed reader<svg class="external-link-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg></a> or add the feed's URL directly
        </div>
        <div class="rss-feed-url-container">
            <div class="rss-feed-url" id="rss-feed-url">https://docs.confluent.io/operator/3.3/release-notes.xml</div>
            <button class="copy-button" onclick="copyRssUrl()" aria-label="Copy RSS feed URL">
                <svg class="copy-icon icon-copy" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"><path d="M360-240q-33 0-56.5-23.5T280-320v-480q0-33 23.5-56.5T360-880h360q33 0 56.5 23.5T800-800v480q0 33-23.5 56.5T720-240H360Zm0-80h360v-480H360v480ZM200-80q-33 0-56.5-23.5T120-160v-560h80v560h440v80H200Zm160-240v-480 480Z"/></svg>
                <svg class="copy-icon icon-check" xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"><path d="M382-240 154-468l57-57 171 171 367-367 57 57-424 424Z"/></svg>
                <span class="rss-sr-only copy-text">Copy</span>
            </button>
        </div>
   </div>
</div>

<script>
function copyRssUrl() {
    const url = 'https://docs.confluent.io/operator/3.3/release-notes.xml';
    const button = event.currentTarget;
    const copyText = button.querySelector('.copy-text');

    // Use modern Clipboard API if available
    if (navigator.clipboard && navigator.clipboard.writeText) {
        navigator.clipboard.writeText(url).then(function() {
            button.classList.add('copied');
            copyText.textContent = 'Copied!';
            setTimeout(function() {
                button.classList.remove('copied');
                copyText.textContent = 'Copy';
            }, 2000);
        }).catch(function(err) {
            console.error('Failed to copy: ', err);
            fallbackCopy(url, button, copyText);
        });
    } else {
        fallbackCopy(url, button, copyText);
    }
}

function fallbackCopy(text, button, copyText) {
    // Fallback for older browsers
    const textArea = document.createElement('textarea');
    textArea.value = text;
    textArea.style.position = 'fixed';
    textArea.style.opacity = '0';
    document.body.appendChild(textArea);
    textArea.select();
    try {
        document.execCommand('copy');
        button.classList.add('copied');
        copyText.textContent = 'Copied!';
        setTimeout(function() {
            button.classList.remove('copied');
            copyText.textContent = 'Copy';
        }, 2000);
    } catch (err) {
        console.error('Fallback copy failed: ', err);
    }
    document.body.removeChild(textArea);
}
</script>

Confluent for Kubernetes is continuously updated with new features and enhancements. This topic
highlights significant new and updated features, bug fixes, and known limitations in
each release.

- For Confluent Platform and CFK compatibility information, see
  [Confluent Platform](co-supported-environments.md#co-operator-supported-versions).
- For CFK image tags by version, see [Confluent for Kubernetes image tags](co-supported-environments.md#co-operator-image-tags).
- To learn how to install CFK and Confluent Platform, see [Deploy Confluent for Kubernetes](co-deploy-operator.md#co-deploy-operator)
  and [Deploy Confluent Platform using Confluent for Kubernetes](co-deploy-cp.md#co-deploy-cp).

#### NOTE
For the list of security and vulnerability issues fixed in any release,
see [Security Advisories and Security Release Notes](https://support.confluent.io/hc/en-us/sections/360008413952-Security-Advisories-and-Security-Release-Notes).

<a id="co-rn-3-3-1"></a>

## [25 September, 2026] Confluent for Kubernetes 3.3.1 Release Notes

### Compatibility and container images

CFK 3.3.1 allows you to deploy and manage Confluent Platform versions from 7.5.x to 8.3.x on
Kubernetes versions 1.28 - 1.36 (OpenShift 4.15 - 4.22).

The images released in CFK 3.3.1 are:

* `confluentinc/confluent-operator:0.1718.99`
* `confluentinc/confluent-init-container:3.3.1`
* `confluentinc/confluent-observer-container:3.3.1`

### Breaking changes

There are no breaking changes in this release.

### New features

* Adds `kubectl confluent block-reconcile` and `kubectl confluent
  enable-reconcile` plugin commands. See
  [kubectl confluent block-reconcile](co-plugin-cli/kubectl_confluent_block-reconcile.md#kubectl-confluent-block-reconcile) and
  [kubectl confluent enable-reconcile](co-plugin-cli/kubectl_confluent_enable-reconcile.md#kubectl-confluent-enable-reconcile).

### Enhancements

* Removes hard-coded `ParallelGCThreads=1` or `ConcGCThreads=1` JVM
  defaults. See [Default JVM settings](co-configure-misc.md#co-default-jvm-settings).
* Adds `spec.configId` to the Confluent Gateway custom resource (CR) for tracking
  hot-reload configuration revisions.
* Adds a pod annotation that triggers a `kubelet` sync for faster
  Confluent Gateway hot-reload.
* Adds `InternalClientConfig` override support for the operator’s internal
  Kafka client. See [Disable TLS hostname verification for the Kafka internal client](co-network-encryption.md#co-disable-internal-client-hostname-verification).
* Unifies Flink Day-2 status refresh on `skipApply` to pull through
  reconcile.

### Bug fixes

* Fixed Jolokia configuration options not rendering as a single
  comma-separated line.
* Fixed the default ZooKeeper `chroot` to root during KRaft migration for MRC
  endpoints.
* Fixed a Cluster Linking issue where non-OAuth secrets were finalized
  prematurely while the operator was still resolving the authentication type.
* Fixed Cluster Linking remote-auth secrets not mounting on Kafka brokers.
* Fixed RBAC drift in the Operator Lifecycle Manager (OLM) bundle.
* Fixed component startup failures on Confluent Platform 8.3.x for components that
  authenticate using OAuth client assertions, by allow-listing the
  client-assertion private-key file.
* Fixed Kafka-to-ZooKeeper TLS connections crash-looping under Federal Information
  Processing Standards (FIPS) mode due to a missing `BCFKS`
  keystore/truststore configuration.
* Fixed the Metadata Service (MDS) client `keystore` rendering for the `mtls` type
  without `sslClientAuthentication`.
* Fixed `spec.tls.fips.enabled: true` not being applied to the embedded
  Kafka REST proxy’s Metadata Service (MDS) client TLS configuration, which was always
  generated as `JKS` instead of `BCFKS`. Manual
  `kafka.rest.client.ssl.*` configuration overrides are no longer needed to run
  FIPS and RBAC deployments together.
* Fixed a `java.security.properties` path typo that silently prevented
  FIPS enforcement from taking effect.
* Fixed the `KafkaTopic` controller so it keeps retrying replication
  factor (RF) fetches after a transient failure, instead of giving up
  permanently. The bug left `status.replicas` empty for topics created
  with `spec.replicas` unset, and was most noticeable when creating
  many topics at once through Helm. Broker-side RF was always correct.
  Only the `KafkaTopic` status was affected.
* Fixed reconcile errors and a stale cluster phase being hidden in
  `Kafka` status. Status, Kubernetes events, and broker logs now surface
  the actual failure reason and cluster phase instead of generic or
  missing messages. This helps diagnose and recover from issues faster.
* Fixed an unnecessary full cluster roll caused by a stale cached read of
  tracked secret versions.
* Fixed observer certificate rotation triggering an unnecessary cluster roll.
* Fixed CFK triggering unnecessary Kafka or KRaftController rolling restarts
  on metadata-only writes to a tracked secret. CFK now detects secret
  changes by content instead of `resourceVersion`.
* Fixed the Replicator `mTLS` connector plugin version.
* Fixed excessive LDAP load caused by each mirror topic independently
  triggering an OAuth token request. Tokens are now batched and cached,
  preventing LDAP overload at scale.
* Fixed `FlinkEnvironment` creation being rejected by CMF due to a name
  collision between `metadata.name` and the top-level `name` field.
* Fixed Common Expression Language (CEL) validation for `passthroughConfig`
  on the Confluent Gateway CR.
* Fixed Confluent Gateway authentication-swapping validation so
  `oauthSettings.jwksEndpointUri` is required only when swapping to OAuth
  authentication, and `oauthSettings.audience` is no longer always
  required.
* Fixed the CMF ownership annotation for `FlinkStatement`.
* Fixed a Schema resource that could report `status.appState: Created`
  without the schema actually being registered in Schema Registry, following a
  reconcile interrupted at a specific point. Affected resources now
  self-heal on the next reconcile.
* Fixed Kafka CR reconciliation failures caused by TLS
  secrets (for example, `services.kafkaRest` mTLS) that contained only
  `JKS` or `PKCS12` material. Previously, only PEM-style secrets were
  supported.
* Fixed an operator memory leak caused by idle outbound HTTP connections
  that were never closed, which could cause gradual memory growth and
  potential `OOMKilled` restarts. Idle connections now close after a
  configurable timeout set by `CONFLUENT_OPERATOR_HTTP_IDLE_CONN_TIMEOUT`,
  which defaults to 90 seconds. See [Deploy CFK with custom environment variables](co-cfk-settings.md#co-deployment-custom-vars).
* Fixed the default OpenID Connect (OIDC) session token expiry,
  increasing it from 90 seconds to 15 minutes.
* Fixed TLS handshake errors flooding Control Center Prometheus and Alertmanager
  logs, caused by Kubernetes health checks against TLS-enabled endpoints.
  Set `useProcNetPortCheck: true` under `spec.podTemplate.probe.readiness`
  or `spec.podTemplate.probe.liveness` on the `ControlCenter` CR to
  switch these health checks to a TLS-free method.
* Fixed an issue that prevented installing or pinning to a specific,
  non-latest, CFK version through the OpenShift OperatorHub. Each release
  now retains a direct upgrade link to its predecessor in the Red Hat
  operator catalog.

### Known limitations

There are no new known limitations in this release.

### Known issues

* On a new KRaft controller deployment, CFK doesn’t automatically set
  `inter.broker.listener.name` on the KRaftController, regardless of CFK
  version. If this property is unset, it defaults to `null` and Self-Balancing
  fails to start. As a workaround, set
  `inter.broker.listener.name=REPLICATION` through `configOverrides` on
  the KRaftController CR. In CFK 3.3 and later, you can instead set
  `spec.listeners.replication.enabled: true` on the KRaftController CR to
  have CFK set the property automatically. For details, see
  [Configure KRaft controllers](co-configure-kraft.md#co-configure-kraft-controller).

### Deprecations

There are no new deprecations in this release.

<a id="co-rn-3-3-0"></a>

## [23 June, 2026] Confluent for Kubernetes 3.3.0 Release Notes

### Compatibility and container images

CFK 3.3.0 allows you to deploy and manage Confluent Platform versions from 7.5.x to 8.3.x on
Kubernetes versions 1.28 - 1.36 (OpenShift 4.15 - 4.22).

The images released in CFK 3.3.0 are:

* `confluentinc/confluent-operator:0.1718.10`
* `confluentinc/confluent-init-container:3.3.0`
* `confluentinc/confluent-observer-container:3.3.0`

### Breaking changes

There are no breaking changes in this release.

### Upgrade considerations

Flink custom resources (CRs) now require co-location with their
FlinkEnvironment. A FlinkApplication, and the preview Flink SQL CRs, must be
created in the same namespace as the FlinkEnvironment it references through
`spec.flinkEnvironment`. CFK stamps an environment-rooted owner reference on
these CRs so that deleting the FlinkEnvironment cascades to them, and
Kubernetes owner references cannot cross namespaces.

If you deployed the FlinkEnvironment and FlinkApplication in different
namespaces on an earlier release, the application reports
`status.cmfSync: Failed` after the upgrade until you remediate it. You can
remediate without disrupting running Flink jobs. For the complete step-by-step
procedure, including how to restore the application and safely remove the
now-redundant FlinkEnvironment, see [Migrate cross-namespace Flink resources](co-manage-flink-environments.md#co-flink-migrate-cross-namespace).

### New features

* Adds preview support for managing Confluent Platform Flink SQL objects through CFK with
  six new custom resources. See [Manage Flink SQL Statements Using Confluent for Kubernetes](co-manage-flink-sql.md#co-manage-flink-sql).
* Expands the FlinkEnvironment and FlinkApplication schemas with new
  configuration and status fields. See [Create a Flink environment](co-manage-flink-environments.md#co-flink-environment).
* Adds support for the migration pre-check utility for single-cluster KRaft migrations. See [Step 3.2: Enable the ZooKeeper metadata preflight check](co-migrate-kraft-procedure.md#co-migrate-kraft-enable-preflight-v2).
* Supports ZooKeeper to KRaft migration for 2.5 datacenter (2.5DC) deployments. See [Two-and-a-half datacenter (2.5DC) considerations](co-migrate-kraft-prerequisites.md#co-migrate-kraft-2-5dc-considerations-v2).
* Supports scaling up KRaftController replicas on dynamic quorum clusters
  without rolling existing controllers or co-located Kafka brokers. See
  [Scale up the controller quorum](co-configure-kraft-dynamic-quorum.md#co-kraft-dynamic-quorum-scale).
* Adds opt-in hot-reload for eligible Gateway configuration changes.
* Adds `mountedSecrets` and `mountedVolumes` to the Gateway CR for mounting
  custom secrets and volumes.
* Supports running the Gateway with `readOnlyRootFilesystem: true` by
  provisioning writable `emptyDir` volumes for the log and temporary file
  paths.
* Supports OAuth-to-OAuth authentication swap through the Gateway. See
  [Configure authentication swapping](gateway/co-gateway-security.md#co-gateway-authn-swap).
* Runs the liveness probe as an `exec` probe backed by the `cfkprober`
  binary. See [Liveness probe change to exec in CFK 3.3.0](co-upgrade-overview.md#co-upgrade-liveness-exec-probe).
* Pauses a maintenance-mode pod inside its main container instead of the init
  container, giving direct access to the component’s command-line tools. See
  [Configure maintenance mode](co-configure-misc.md#co-maintenance-mode).

### Enhancements

* Masks sensitive credentials in CFK log output through a centralized
  redaction wrapper, so plaintext credentials are sanitized before reaching any
  log sink.
* Generates the KRaft admin-client properties file for dynamic quorum
  deployments.
* Revokes the corresponding Metadata Service (MDS) role binding when you remove an entry
  from `spec.resourcePatterns` on the ConfluentRolebinding CR, preventing
  orphaned bindings from persisting. See [Update a rolebinding](co-manage-rbac.md#co-update-rolebinding).
* Supports a new `useProcNetPortCheck` liveness and readiness probe method
  that reports liveness from the `/proc/net/tcp` file instead of performing an
  actual handshake. This helps avoid TLS-related errors.
* Supports adding a sidecar container to a Pod Overlay for in-pod debugging and
  connectivity checks. This has always been possible, but it becomes more
  important starting with Confluent Platform 8.3, because images now use the `ubi9-micro`
  base image instead of `ubi9-minimal` and no longer include `curl` and
  other command-line tools. See [Customize Confluent Platform pods with Pod Overlay](co-configure-misc.md#co-pod-overlay).
* Adds a disaster recovery procedure for recovering a multi-region dynamic
  KRaft cluster after a controller quorum loss. See
  [Disaster Recovery for Multi-Region KRaft Clusters](co-disaster-recovery.md#co-disaster-recovery).

### Bug fixes

* Fixed incorrect `advertised.listeners` ports when multiple user-defined
  listeners share the same static or nodePort offset.
* Fixed dynamic per-listener TLS certificate rotation triggering unnecessary
  Kafka broker rolling restarts. CFK now correctly classifies derived `PKCS12`
  secrets as dynamic-config secrets.
* Fixed the `zk-node-removal` plugin for RBAC and MRC deployments.
* Fixed MRC KRaft migration requiring a manual `zookeeper.connect`
  override on the KRaftController. For 2.5DC topologies, the manual ZooKeeper
  endpoint on the 0.5DC `KRaftController` is still required. See [Configure the IBP version](co-migrate-kraft-mrc.md#co-migrate-kraft-mrc-0-5dc-v2).
* Fixed an orphaned connector when a Connector CR is deleted after a failed
  create or update. CFK now issues the `REST DELETE` instead of skipping it.
* Fixed Jolokia file-reference password resolution to trim whitespace so
  passwords read from mounted secret files no longer fail.
* Fixed client-side `OAUTHBEARER` authentication failing through the Gateway.

### Known limitations

* Components that authenticate to Kafka using OAuth client assertions, such as
  Schema Registry, Connect, ksqlDB, Control Center, and REST Proxy, fail to start on Confluent Platform
  8.3.x. Kafka 4.3 enforces an empty, deny-by-default allowlist for the files
  used in the OAuth client-assertion flow, so the configured private-key file
  is rejected. As a workaround, set the
  `-Dorg.apache.kafka.sasl.oauthbearer.allowed.files` JVM system property on
  the affected component through its `*_OPTS` environment variable or
  `podTemplate`. If you configure issuer or JSON Web Key Set (JWKS) endpoint
  URLs, also set `-Dorg.apache.kafka.sasl.oauthbearer.allowed.urls`.

<a id="co-mrc-rolebinding-limitation"></a>
* In Multi-Region Cluster (MRC) deployments, the co-ownership check only
  considers `ConfluentRolebinding` resources visible to the operator
  managing that cluster. A co-owning `ConfluentRolebinding` on another
  region’s cluster is not visible, so removing a pattern from (or deleting) a
  `ConfluentRolebinding` might revoke a binding that a `ConfluentRolebinding`
  in another region still declares. Use caution when removing patterns or
  deleting `ConfluentRolebinding` resources in MRC if the same
  `(principal, role, scope, resourcePattern)` might be declared on another
  region’s cluster. For details, see [Update a rolebinding](co-manage-rbac.md#co-update-rolebinding).
* A Confluent Gateway passthrough route that configures `cluster.extensionHeaders`
  fails admission validation. Injecting extension headers requires setting
  `client.authentication.type` to `oauth`, which triggers a CRD validation
  rule that mandates `oauthSettings.jwksEndpointUri` and
  `oauthSettings.audience`. Although Confluent Gateway ignores these fields at runtime
  on passthrough routes and forwards tokens unmodified, the validation rule
  still rejects the resource. As a workaround, you must provide placeholder
  values for the required OAuth fields. For details, see
  [OAUTHBEARER passthrough limitation](gateway/co-gateway-security.md#co-gateway-passthrough-oauth-limitation).
* If you manage the CFK `ServiceAccount` permissions manually instead of
  letting Helm create them, CFK 3.3.0 requires additional RBAC permissions
  that earlier versions did not. Without these permissions, the CFK pod
  repeatedly crashes with a `jobs.batch is forbidden` error. For details on
  the required permissions, see [Add RBAC permissions for custom roles before upgrading to 3.3](co-upgrade-overview.md#co-upgrade-custom-rbac-batch-jobs).
* CFK 3.3.x can trigger unnecessary Kafka or KRaftController rolling
  restarts when a metadata-only update changes a tracked secret’s
  `resourceVersion`. As a workaround, set
  `platform.confluent.io/secret-change-roll-cluster="false"` on the
  affected resources. Note that after applying this workaround, intentional
  secret rotations then require a manual roll.
* The operator can leak memory and `goroutines` over time from idle
  outbound HTTP connections (to Kafka REST, Metadata Service (MDS), Schema Registry, or an OAuth
  identity provider) that are never closed. This can affect any deployment.
  Upgrade to CFK 3.3.1 or later, which adds a configurable idle-connection
  timeout to fix this. See [[25 September, 2026] Confluent for Kubernetes 3.3.1 Release Notes](#co-rn-3-3-1).

### Deprecations

There are no new deprecations in this release.
