Skip to content

v3.4 to 3.5

Breaking Changes

Helm was upgraded to 4.2.0.

In Helm v4, the OCI implementation is more strict: if the registry doesn't speak TLS, it is required to explicitly use --plain-http upon helm push, helm registry login and upon helm dependency build.

This is a breaking change for Argo CD users with plain HTTP OCI registries. Two actions may be required:

Set --insecure-oci-force-http on existing OCI repos

For any existing OCI repository that uses plain HTTP (not HTTPS), add the flag via CLI (CLI version 3.5): repo add ... --insecure-oci-force-http --upsert
Or set it directly in the Kubernetes secret:

stringData:
   insecureOCIForceHttp: "true"

Explicitly register plain HTTP dependency repos

If your Helm charts have OCI dependencies (Chart.yaml dependencies with repository: oci://...) hosted on plain HTTP registries, those dependency repos must now be explicitly added to Argo CD with the --insecure-oci-force-http flag, the same way as described above. With Helm v3 this was not required — plain HTTP OCI dependency registries were accessed transparently without registration. With Helm v4, Argo CD needs to know which dependency registries use plain HTTP in order to pass --plain-http to helm dependency build.

Known limitation — conflicting TLS flags (Helm v4)

For Argo CD OCI repo, setting both --insecure-skip-server-verification (passed to Helm as --insecure-skip-tls-verify) and --insecure-oci-force-http (passed to Helm as --plain-http) causes Helm v4 to silently drop --plain-http, as --insecure-skip-tls-verify takes internal precedence. Plain HTTP registry operations then fail with http: server gave HTTP response to HTTPS client. This affects:

  • Argo CD repos with type=helm with --enable-oci: having both flags on the same repo causes the chart pull to fail.
  • Argo CD repos with type=oci and type=helm with dependencies: --insecure-skip-server-verification on the main repo combined with --insecure-oci-force-http on any dependency repo causes dependency build to fail.

There is no workaround when both configurations are legitimately required in the same chain.

Applications with spec.source.helm.version setting

If you historically have the following setting on your Helm application, the setting is ignored and Argo CD will use Helm v4 only to render your charts:

spec:
  source:
    helm:
      version: v3

You are not required to update or remove this field, and can leave this setting as is.

UI extensions must externalize react/jsx-runtime

The Argo CD UI was upgraded from React 16 to React 19 in 3.5. UI extensions built against an older Argo CD UI may fail to load with a TypeError until they are rebuilt to externalize react/jsx-runtime.

The host UI surfaces the failure as:

Extension <name>.js failed to load: TypeError: Cannot read properties of undefined (reading '<prop>')

See UI Extensions: React 19 Upgrade for the full remediation guide.

No action is required for users that do not install UI extensions.

Event-listing gRPC methods now return an Argo CD EventList type

Argo CD 3.5 changes the gRPC response type of the event-listing APIs from k8s.io.api.core.v1.EventList to an Argo CD-defined EventList type to remain compatible with newer Kubernetes protobuf definitions without exposing the Kubernetes protobuf type directly in Argo CD's public gRPC surface.

The affected gRPC methods are:

  • application.ApplicationService/ListResourceEvents
  • applicationset.ApplicationSetService/ListResourceEvents
  • project.ProjectService/ListEvents

Impact on gRPC clients

Any generated or custom gRPC client that calls these methods must be regenerated or upgraded together with the Argo CD 3.5 server.

This includes any program or script that directly invokes the affected event-listing RPCs. Using the grpc-web protocol is not a compatibility workaround for this change.

The Argo CD CLI does not use these APIs and so it is not affected.

Impact on REST clients and the UI

The REST endpoints and paths remain unchanged:

  • GET /api/v1/applications/{name}/events
  • GET /api/v1/applicationsets/{name}/events
  • GET /api/v1/projects/{name}/events

The JSON response body continues to use the same EventList-shaped payload, so the Argo CD UI and any REST integrations that consume these endpoints as JSON are not impacted.

OpenAPI / schema note

Although the REST paths and JSON payload remain the same, the generated OpenAPI schema for these endpoints now uses Argo CD's eventsEventList definition instead of io.k8s.api.core.v1.EventList.

If you generate REST clients from Argo CD's OpenAPI definition, treat this as a schema-level breaking change and regenerate or update those clients during the upgrade.

Behavioral Improvements / Fixes

Impersonation extended to server operations

When impersonation is enabled, it now applies to all API server operations, not just sync operations. This means that actions triggered through the UI or API (viewing logs, listing events, deleting resources, running resource actions, etc.) will use the impersonated service account derived from the AppProject's destinationServiceAccounts configuration.

Previously, impersonation only applied to sync operations.

Affected operations and required permissions:

Operation Kubernetes API call Required RBAC verbs
Get resource GET on the target resource get
Patch resource PATCH on the target resource get, patch
Delete resource DELETE on the target resource delete
List resource events LIST on events (core/v1) list
View pod logs GET on pods and pods/log get
Run resource action GET, CREATE, PATCH on the target resource get, create, patch

This list covers built-in operations. Custom resource actions may require additional permissions depending on what Kubernetes API calls they make.

Users with impersonation enabled must ensure the service accounts configured in destinationServiceAccounts have permissions for these operations.

No action is required for users who do not have impersonation enabled.

SSH known_hosts now used for repositories without configured credentials

Argo CD upgraded go-git to v5.19.x, which tightens SSH host-key verification. To keep host-key validation working against the Argo CD–managed argocd-ssh-known-hosts-cm ConfigMap (and to avoid knownhosts: key mismatch handshake failures with the new go-git), Argo CD now builds the SSH auth itself for repositories that don't have explicit credentials configured.

Previously, when an SSH repository URL had no credentials configured in Argo CD, the repo server let go-git fall back to its default auth builder, which constructs an ssh-agent-based auth and reads known_hosts from ~/.ssh/known_hosts (or $SSH_KNOWN_HOSTS) inside the repo-server container. Now, Argo CD builds the same ssh-agent-based auth itself but wires the host-key callback to the argocd-ssh-known-hosts-cm ConfigMap, matching the behavior of repositories that do have credentials configured.

If your repo server image / pod previously relied on a custom ~/.ssh/known_hosts (e.g. baked into a custom image or mounted in via a volume) for SSH repositories without configured credentials, add those host keys to argocd-ssh-known-hosts-cm instead.

No action is required for users who only access SSH repositories with credentials configured in Argo CD, or who access only HTTPS repositories.

GnuPG signature verification replaced by Source Integrity

The GnuPG key verification feature has been replaced by Source Integrity, a more versatile subsystem for verifying the integrity of application sources.

Consult Upgrade to Source Integrity Verification section for the migration details.

Legacy configurations will continue to function temporarily (issuing a warning) to facilitate migration.

No action is required for users that do not use GnuPG signature verification.

API Changes

Security Changes

Deprecated Items

GnuPG signature configuration

  • Modification of project signature keys using argocd proj add-signature-key and argocd proj remove-signature-key is deprecated.
  • Declaring .spec.signatureKeys in AppProject is deprecated.

Configure sourceIntegrity in AppProject YAML instead.

GnuPG signature verification result

  • Reading GnuPG verification results from verifyResult in REST API is deprecated.

Consume structured result from sourceIntegrityResult field instead.

Kustomize Upgraded

Helm Upgraded

Helm was upgraded to 4.2.1, resulting in some breaking changes described in the Breaking changes section of this doc.

Custom Healthchecks Added

Other Changes

Release sbom.tar.gz contents

For normal GitHub releases, sbom.tar.gz still includes bom-go-mod.spdx (Go dependencies, tag-value SPDX from spdx-sbom-generator) and bom-docker-image.spdx (the published release image, tag-value SPDX from sigs.k8s.io/bom). The UI dependency list is now bom-ui-pnpm.spdx.json: SPDX 2.3 JSON from pnpm sbom, replacing the old tag-value ./ui output from spdx-sbom-generator.

If you consume this archive with tooling that only looked at *.spdx files, extend it to handle bom-ui-pnpm.spdx.json as well, or verify sbom.tar.gz using argocd-sbom.intoto.jsonl without depending on a fixed internal file list.

mTLS support for repo-server

mTLS is opt-in and disabled by default — no action is required for operators who do not configure it.

To enable mTLS, create the argocd-repo-server-mtls Secret with the following keys:

apiVersion: v1
kind: Secret
metadata:
  name: argocd-repo-server-mtls
  namespace: argocd
type: Opaque
stringData:
  client-ca.crt: |
    <PEM-encoded CA certificate that signed the client certs>
  client.crt: |
    <PEM-encoded shared client certificate>
  client.key: |
    <PEM-encoded private key for the shared client certificate>

The Secret is automatically mounted at /app/config/reposerver/mtls in every relevant pod. All components default to reading their cert/key/CA files from that mount path, so mTLS is enabled automatically as soon as the Secret exists — no ConfigMap changes, flag overrides, or additional configuration are required.

Key points:

  • Repo server (server-side):
  • --client-ca-path defaults to /app/config/reposerver/mtls/client-ca.crt (the auto-mounted Secret path). mTLS is enabled when the file exists; silently skipped if absent.
  • Cannot be combined with --disable-tls.
  • Server TLS cert/key are loaded from /app/config/reposerver/tls/tls.crt and /app/config/reposerver/tls/tls.key.
  • Clients (argocd-server, application-controller, applicationset-controller, notifications-controller):
  • --repo-server-client-cert-path defaults to /app/config/reposerver/mtls/client.crt; mTLS client cert is skipped if the file does not exist.
  • --repo-server-client-cert-key-path defaults to /app/config/reposerver/mtls/client.key; mTLS client cert is skipped if the file does not exist.
  • --repo-server-ca-cert-path is optional and used if the repo-server’s server certificate is signed by a custom CA.

Operational notes:

  • When mTLS is enabled on repo-server, it automatically generates an ephemeral client certificate for its own liveness self-check; you do not need to modify probes.
  • Equivalent environment variables and argocd-cmd-params-cm ConfigMap keys exist for all settings above; see the linked docs for names and examples.

See the dedicated mTLS documentation for full setup instructions, per-component cert options, verification steps, and troubleshooting.

The --repo-server-strict-tls flag (deprecated in favor of --repo-server-ca-cert-path)

The --repo-server-strict-tls boolean flag is deprecated across all components: - argocd-server - argocd-application-controller - argocd-applicationset-controller - argocd-notification

Reason for deprecation: The old flag used implicit behavior (automatically loading embedded certificates from /app/config/server/tls/), making it difficult to maintain consistency across components. The new approach is more explicit and aligns with Kubernetes Secret mounting patterns.

Important: This deprecation does NOT affect TLS capabilities. Operators can still configure TLS-only connections (without mTLS) using the new flag.

Migration Guide

The deprecated flag will continue to work in 3.5 (with warnings), but you should migrate to the new approach:

Option 1: Migrate to --repo-server-ca-cert-path (Recommended)

Replace the deprecated flag with an explicit CA certificate path:

# Before (3.4 and earlier):
argocd-server \
  --repo-server-strict-tls

# After (3.5):
argocd-server \
  --repo-server-ca-cert-path=/app/config/server/tls/ca.crt

Kubernetes manifests:

# Before:
spec:
  containers:
  - name: argocd-server
    args:
    - argocd-server
    - --repo-server-strict-tls
    volumeMounts:
    - name: server-tls
      mountPath: /app/config/server/tls

# After:
spec:
  containers:
  - name: argocd-server
    args:
    - argocd-server
    - --repo-server-ca-cert-path=/app/config/server/tls/ca.crt
    volumeMounts:
    - name: server-tls
      mountPath: /app/config/server/tls

Option 2: Use environment variable (Alternative)

Instead of a flag, use the corresponding environment variable:

# Before:
argocd-server --repo-server-strict-tls

# After:
export ARGOCD_SERVER_REPO_SERVER_CA_CERT_PATH=/app/config/server/tls/ca.crt
argocd-server

Option 3: Continue using deprecated flag (Not recommended, temporary only)

The flag will continue to work in 3.5 but will issue a deprecation warning. Using both flags together is supported:

# This continues to work in 3.5 (but will show deprecation warning):
argocd-server \
  --repo-server-strict-tls \
  --repo-server-ca-cert-path=/app/config/server/tls/ca.crt

Backward Compatibility

  • Both flags work together using OR semantics: if either is set to true, strict validation is enabled
  • No functionality is lost; TLS validation capabilities remain unchanged
  • The new flag is more explicit and maintainable

Timeline

  • v3.5: Deprecated flag still works (with warnings)
  • v3.6+: Flag may be removed; plan migration accordingly

All components affected (server, application-controller, applicationset-controller, notification-controller) follow the same migration pattern.