Back to Dapr

Dapr 1.18

docs/release_notes/v1.18.0.md

1.18.086.3 KB
Original Source

Dapr 1.18

We're excited to announce the release of Dapr 1.18! This is primarily a Workflows release, focused on security, durability, and scale. Workflow history can now optionally be cryptographically signed and verified on every state load, so tampering is caught the moment state is read. The same protection extends across application boundaries: child workflow and activity completions are attested between apps. A new WorkflowAccessPolicy resource controls which application IDs may invoke which workflows and activities. Workflows can also propagate slices of their history to the children they schedule, letting a child act on upstream context instead of reading it back from a state store. And the Scheduler gained global and per-name concurrency limits that cap how many workflows or activities run at once across the cluster.

Outside of Workflows, the Jobs API graduates to stable, hot-reloading of components and other resources is now GA and on by default, and the sidecar injector understands Kubernetes native sidecar containers. This release also introduces a new MCPServer resource that exposes Model Context Protocol tool calls as durable Dapr Workflows. Several changes make the control plane steadier under load: an opt-in coalesce window collapses redundant placement dissemination rounds during large scale-ups, placement and scheduler support hard anti-affinity, host resolution now works over IPv6 and dual-stack, and pub/sub drains in-flight messages on graceful shutdown instead of dropping them.

Before you upgrade, note one change in Sentry. It now generates workload identity keys using Ed25519 instead of ECDSA. This is invisible on a fresh install or a normal upgrade, but it means you cannot safely roll back below 1.17.7. See the new Downgrading section for the safe rollback path.

Thanks to all the new and existing contributors who helped make this release happen.

If you're new to Dapr, visit the getting started page and familiarize yourself with Dapr.

The docs have been updated with all the new features and changes of this release. To get started with new capabilities introduced in this release, go to the Concepts and the Developing applications.

Note: This release contains a few breaking changes.

Go to the upgrading Dapr section for steps to upgrade to version 1.18.

Acknowledgements

Thanks to everyone who made this release possible!

@1Ninad, @acroca, @alekhrycaiko, @antontroshin, @artur-ciocanu, @aviralgarg05, @bibryam, @CasperGN, @cerebrixos, @cicoyle, @Copilot, @cyphercodes, @Eckii24, @erj826, @erwinkramer, @famarting, @gaganhr94, @imneov, @ja-sg, @javier-aliaga, @Jeevansm25, @jjcollinge, @jmfloreszazo, @JoshVanL, @lrascao, @marcduiker, @matheusandre1, @MichaelHindley, @middt, @mikeee, @mohitpalsingh, @MukundaKatta, @MyMirelHub, @nelson-parente, @nikitasarawgi, @officialasishkumar, @olitomlinson, @pablochacin, @Pittu-Sharma, @pravinpushkar, @Rishabh-git10, @salaboy, @seherv, @sicoyle, @siri-varma, @spolom, @stywzn, @vaibhavatlan, @WhitWaldo, @yaron2, @ZeynelKoca

Highlights

These are the v1.18 release highlights:

WorkflowAccessPolicy

WorkflowAccessPolicy is a new Kubernetes CRD that controls which Dapr app IDs are allowed to operate on which workflows running on a target app. Before v1.18, any caller in the same trust domain could schedule, terminate, or query any other app's workflows. That was acceptable for single-team clusters but a real problem in shared or multi-tenant ones, especially now that workflows can branch into remote apps where unrestricted cross-app calls are a security risk.

The policy is a pure allow-list:

  • With no policy loaded for a target app, every call is allowed — open by default, so existing deployments are unaffected.
  • With one or more policies loaded, the target defaults to deny, and only calls matching a rule are permitted.
  • Self-calls (where the caller's app ID equals the target's) are always allowed and need no rule.

Caller identity comes from the SPIFFE identity in the mTLS certificate for remote calls, and from the local app ID for same-sidecar calls. Untrusted identity headers on user-facing requests are stripped before evaluation, so one app cannot spoof another's identity.

Rules are expressed per operation. Workflows support all eight operations — schedule, terminate, raise, pause, resume, purge, get, and rerun — while activities support schedule only. Names can be exact or glob patterns (*, ?, [abc]).

Example:

yaml
apiVersion: dapr.io/v1alpha1
kind: WorkflowAccessPolicy
metadata:
  name: orders-policy
  namespace: production
scopes:
  # the target apps that load and enforce this policy
  - orders-target
spec:
  rules:
    # Frontend and ops-console can schedule and terminate OrderWF.
    - callers:
        - appID: frontend
        - appID: ops-console
      workflows:
        - name: OrderWF
          operations: [schedule, terminate]

    # Frontend can also schedule the ChargePayment activity directly.
    - callers:
        - appID: frontend
      activities:
        - name: ChargePayment
        - name: "RefundEvent*"

When a call is denied, the caller receives an opaque error (access denied by workflow access policy) that doesn't reveal which rule matched or what the policy would otherwise allow.

For configuration and examples, see How-To: Apply workflow access policies and the WorkflowAccessPolicy spec. For background, see Workflow access control in the security concepts.

Workflow History Tamper Detection

Workflow history events can now be optionally cryptographically signed and verified. Each step's signature is produced under the sidecar's mTLS X.509 SPIFFE identity and chained to the previous one, creating an auditable signature chain that is checked on every state load.

Each workflow execution step produces a batch of history events that are signed and chained to the previous signature:

  ┌─────────────────────────────────────────────────────────────┐
  │                    Workflow History                         │
  │  Event 0 ─ Event 1 ─ Event 2 ─ Event 3 ─ Event 4 ─ Event 5  │
  └─────┬──────────┬─────────┬──────────┬─────────┬──────────┬──┘
        ▼          ▼         ▼          ▼         ▼          ▼
  ┌──────────────────┐  ┌──────────────────┐  ┌──────────────────┐
  │    Signature 0   │  │    Signature 1   │  │    Signature 2   │
  │  Events [0,2)    │  │  Events [2,4)    │  │  Events [4,6)    │
  │  prevDigest: nil ├─►│ prevDigest: d0   ├─►│  prevDigest: d1  │
  └──────────────────┘  └──────────────────┘  └──────────────────┘

On every state load, the runtime verifies:

  • chain linkage between signatures (prevDigest),
  • event contiguity (no gaps in the [start, end) ranges),
  • digest recomputation matches the signed digest,
  • the signature itself,
  • certificate validity at event time, and
  • the signing app's SPIFFE identity matches the workflow's owning app ID.

If verification fails, the actor appends a terminal ExecutionCompleted event with the well-known error type DAPR_WORKFLOW_HISTORY_TAMPERED, terminates the in-flight workflow, and leaves the original (untrusted) state intact for forensic inspection.

Two additional layers extend the same integrity guarantee across app boundaries:

  • Child workflow and activity completion attestation — before a child workflow or activity reports back to its parent, the executor signs a ChildCompletionAttestation / ActivityCompletionAttestation that commits to the parent instance ID, parent task scheduled ID, a canonical input/output digest (SHA-256 over a wire-format-independent, NFC-normalized encoding so the digest is stable across language SDKs), the signer's certificate chain digest, and the terminal status. The parent verifies the attestation on inbox ingestion and stores the foreign signer's certificate in the ext-sigcert table, keyed by certificate-chain digest.
  • Cryptographic verification of propagated history — every chunk of propagated history now carries its own chunk-local signature and DER cert chain, produced at dispatch time by the chunk's owning app. Receivers verify each chunk against the Sentry trust anchor and check that the leaf SPIFFE ID's app component matches chunk.appId.

Signing is a one-way decision. Once a workflow is created with signing enabled, its history must stay signed — disabling signing for that workflow (or enabling it on one that started unsigned) is a hard verification error, and there is no catch-up signing of pre-existing events. Before turning signing on cluster-wide, let any in-flight unsigned workflows complete or purge them. The feature is gated by the WorkflowHistorySigning configuration feature flag, requires mTLS to be active (daprd refuses to start with signing enabled but mTLS off), and is disabled by default in v1.18.

See Workflow history signing for how to enable signing, the verification model, and the cross-app attestation guarantees.

Workflow History Context Propagation

Workflows can now propagate slices of their history down to child workflows and activities, where the consumer can query it by name.

Two opt-in propagation modes are supported:

  • Lineage — the full ancestor chain of workflow history is propagated to children.
  • OwnHistory — only the current workflow's own history is propagated to its immediate children.

Propagation is per call: the caller decides whether — and what — to propagate when scheduling a child workflow or activity, and the consumer reads it back through a typed query API (for example, fetching a previously-completed activity's result by workflow name and activity name). This avoids threading state through inputs or reaching into a state store, the latter of which would break workflow determinism.

See Workflow history propagation for the Lineage and OwnHistory modes and the typed query API.

Workflow Concurrency Limits

Workflow and activity concurrency can now be capped at the scheduler, across all sidecar replicas, alongside the existing per-sidecar limits. You can set a global maximum across all workflows or activities, plus per-name limits for specific workflow or activity names.

When a limit is hit, the scheduler holds triggers in a pending queue and dispatches them as slots free up via the existing ACK protocol. Global limits are sharded deterministically across scheduler instances: each replica enforces an even share of the limit, with the remainder handed to the lowest-indexed replicas so the cluster-wide total matches what you configured. Per-name limits run as independent gates, and a trigger must pass every applicable gate before it dispatches. There is one edge case: if a global limit is set lower than the number of scheduler replicas, each replica still allows one concurrent invocation to avoid starvation, so the effective cap can exceed the configured value.

yaml
spec:
  workflow:
    globalMaxConcurrentWorkflowInvocations: 50
    globalMaxConcurrentActivityInvocations: 200
    activityConcurrencyLimits:
      - name: SendEmail
        maxConcurrent: 5
    workflowConcurrencyLimits:
      - name: OrderProcess
        maxConcurrent: 20

See Workflow concurrency limits for how to configure the global and per-name limits.

Graceful Stall on Oversized Workflow Payloads

Previously, a workflow whose history payload (PastEvents + NewEvents + PropagatedHistory) exceeded the Dapr API gRPC server's MaxSendMsgSize (= --max-body-size, default 4 MiB) caused stream.Send on the GetWorkItems server stream to return ResourceExhausted. The whole stream was torn down, cancelling every other workflow pending on it. The SDK would reconnect, and the same offending workflow would fail again, in a loop.

In v1.18, the orchestrator precomputes the proto size of the dispatch a workflow (or activity) would produce and compares it against 95% of --max-body-size. The 5% headroom covers the WorkflowStarted event the engine injects plus gRPC framing. Anything over the threshold is gracefully stalled in a recoverable state, leaving the rest of the stream untouched. The runtime emits the payload size as a ratio of the limit so operators can watch the distribution, and a stalled instance resumes once you raise --max-body-size and restart daprd. No instance is lost.

See Workflow payload size limits for the stall behavior, the payload-size ratio metric, and how to recover a stalled instance.

Workflow External Event Timers

A WaitForExternalEvent wait with no timeout used to be invisible to the runtime: from the outside, there was no way to tell what an instance was blocked on. In v1.18 such an indefinite wait materialises a synthetic timer (with a fire-at far enough in the future that it never actually fires), tagged with an origin that records the name of the event being awaited. With the existing RaiseEvent API, this makes approval gates and other human-in-the-loop workflows operable. The same timer-origin field also distinguishes timers created as activity and child-workflow retry delays, so every timer in a workflow's history now records why it was created.

See External events and the external system interaction pattern for how to author approval gates and other human-in-the-loop workflows using WaitForExternalEvent and RaiseEvent.

Jobs API is now Stable

The Jobs API graduates to stable in v1.18. Performance regression tests were added as part of the stabilization work to guard against future regressions.

You should move application code to the stable ScheduleJob / GetJob / DeleteJob endpoints and the OnJobEvent callback. The alpha RPCs (ScheduleJobAlpha1 and friends) are now deprecated but remain fully functional, and the transition needs no coordination: a 1.18 sidecar still serves the alpha RPCs for older clients, and updated SDK clients fall back to the alpha RPCs automatically when they detect an older sidecar. You can upgrade the runtime and migrate application code separately.

HotReload is now GA

Configuration and component hot-reloading graduates to GA and is on by default in v1.18. The following resources are hot-reloadable without restarting the sidecar:

  • Components
  • Subscriptions
  • MCPServers
  • Configurations
  • HTTPEndpoints
  • Resiliencies
  • WorkflowAccessPolicies

The Subscription reconciler now skips the close+reopen when an incoming Subscription event is functionally identical to the one already loaded. This fixes a startup race where the boot-time loader and the operator stream both delivered the same subscription, which previously caused transient subscriber overlap and occasional duplicated or lost messages.

Operators who want the pre-1.18 behavior can opt out by disabling the HotReload feature in the Dapr Configuration — add it to spec.features with enabled: false.

MCPServer Resource — Built-in Workflow Orchestration for MCP

A new MCPServer Kubernetes CRD, plus a built-in workflow orchestration engine, exposes Model Context Protocol (MCP) servers through the standard Dapr Workflow API.

When a sidecar loads one or more MCPServer resources, daprd registers built-in dapr.internal.mcp.<server>.ListTools and dapr.internal.mcp.<server>.CallTool.<toolName> workflow orchestrations. These execute MCP protocol calls as durable activities, so application code doesn't need to import an MCP SDK, manage connections, or handle credentials. The runtime handles all of that, with the same durability guarantees as any Dapr workflow.

  • Transports: streamable_http, sse, stdio.
  • Auth: static header injection, OAuth2 client credentials (secret fetched at call time from Dapr secret stores with retryable error handling), and SPIFFE JWT SVID injection.
  • Spec-compliant: both ListTools and CallTool follow the MCP specification. ListTools returns each tool's name, description, and inputSchema exactly as the server advertises them, without flattening, renaming, or rewriting the schema. CallTool preserves the full CallToolResult shape, including the content union (text, image with base64 + mimeType, audio with base64 + mimeType, resource_link with URI and metadata, and embedded resource with inlined text or blob), the isError flag, and any server-provided metadata. JSON-RPC envelopes pass through unmodified. Unknown or future content types fall back to a structured JSON envelope rather than being dropped, so the path stays compatible with new MCP revisions.
  • Lifecycle hooks: beforeCallTool, afterCallTool, beforeListTools, afterListTools, each able to mutate arguments / results.
  • Only loaded when used: the MCP executor is wired in only when at least one MCPServer resource is loaded, so sidecars with no MCP resources incur no MCP-related allocations.

The preview feature gate was removed before GA; loading the CRD is now the only opt-in (#9838).

Placement: Coalesce Window + Stable Scheduler Reload

Two improvements to placement dissemination behavior at scale:

  • Stable scheduler reload (always on). The actor-type list returned by actorTable.Types() is built by ranging a map, so its order was non-deterministic. scheduler.ReloadActorTypes compares that list against the last-seen one to decide whether to reconnect, and the reordering alone made it look changed — triggering spurious reconnects on rounds where nothing actually had. It now sorts the list and skips the reconnect when the sorted set is unchanged.
  • Post-round coalesce window (opt-in). A new --disseminate-coalesce-window flag (default 0 = disabled). When set, after a dissemination round completes with queued host registers/disconnects, the disseminator arms a one-shot timer instead of starting the next round immediately. Additional host events arriving inside the window accumulate and fold into a single follow-up round. The first event in an otherwise idle state still fires a round immediately, so cold-starts and isolated churn stay responsive; only sustained bursts pay the (configurable) latency to save rounds.

For 100+-replica scale-ups or rolling restarts, the coalesce window collapses what would have been O(N) follow-up rounds into O(1), removing N-1 rounds of drain+halt cost from every existing daprd in the namespace. Recommended values are 100–250 ms for clusters with frequent rapid churn. Default 0 preserves the existing behavior.

Placement & Scheduler: Hard Anti-Affinity

A configurable HA pod anti-affinity policy for the placement and scheduler StatefulSets in the Helm chart:

  • preferredDuringSchedulingIgnoredDuringExecution (default): soft anti-affinity; the Kubernetes scheduler tries to spread replicas but can still place pods when capacity is limited.
  • requiredDuringSchedulingIgnoredDuringExecution: hard anti-affinity; enforces replica separation and may leave pods pending if constraints cannot be satisfied.

Configured via global.ha.podAntiAffinityPolicy, and combinable with global.ha.topologyKey to choose the spread domain (e.g. topology.kubernetes.io/zone, kubernetes.io/hostname). The other control-plane components (operator, sentry, injector) continue to use the soft policy.

See Spreading Placement and Scheduler replicas in the production guidelines for how to configure global.ha.podAntiAffinityPolicy and global.ha.topologyKey.

Actor APIs: App-Initiated gRPC Streams

Actor hosts (the application side) can now open a single bidirectional gRPC stream to daprd via SubscribeActorEventsAlpha1 and receive all four callback types — invoke, reminder, timer, and deactivate — over that one connection. Apps no longer need to expose an HTTP or gRPC server port for daprd to call into; the connection flows app → sidecar, mirroring how pubsub subscriptions, configuration watch, and scheduler job streams already work.

It also makes actor hosts deployable behind tighter firewall and NetworkPolicy rules, since there's no inbound port to allow.

Sidecar Probe Defaults Tuned for Production

Liveness probes are only appropriate as a last-resort restart mechanism for software you don't own. For processes Dapr owns, short liveness windows turn transient blips (GC pauses, startup work, brief stalls) into restart loops. Readiness is the correct lever for routing traffic away from an unhealthy replica.

v1.18 pushes liveness well past any plausible real-world stall (~230 s before kubelet restart) while making readiness more responsive:

Liveness (control plane + injected sidecar):
  initialDelaySeconds: 180
  periodSeconds:        10
  failureThreshold:      5     (~230s before restart)

Readiness (control plane, few replicas — eject fast on failure):
  initialDelaySeconds: 1
  periodSeconds:       1
  failureThreshold:    3       (~3s to eject)

Readiness (daprd sidecar, more forgiving for user workloads):
  initialDelaySeconds: 1
  periodSeconds:       1
  timeoutSeconds:      1
  failureThreshold:    5       (~5s to eject; absorbs brief GC / CPU stalls)

See Sidecar health for the probe defaults, and the arguments and annotations reference for the dapr.io/sidecar-liveness-probe-* and dapr.io/sidecar-readiness-probe-* annotations used to override them.

Sentry: Ed25519 Workload Identity Keys

Sentry and workloads now generate X.509 certificate keys using Ed25519 instead of ECDSA P-256 for all workload identity. The migration is invisible on a fresh install or a normal upgrade.

  • Root CA and issuer CA keys are now Ed25519; the X.509 signature algorithm changes from ECDSAWithSHA256 to PureEd25519.
  • Sentry's CA accepts CSRs of any supported algorithm (Ed25519, RSA, ECDSA), so mixed-version clusters during a rolling upgrade are fully supported — a 1.17.x daprd presenting an ECDSA CSR is still signed by a 1.18 sentry.
  • JWT signing remains RSA-2048 for cloud provider OIDC compatibility.
  • Injector and operator continue using RSA keys for their webhook serving certificates (#9873), because some managed Kubernetes distributions reject Ed25519 on admission webhooks.

Downgrade implications. Sentry versions before 1.17.7 cannot parse the Ed25519-keyed trust bundle that 1.18 writes to the dapr-trust-bundle secret and will crash on startup with unsupported key type ed25519.PrivateKey. See the new Downgrading to Earlier Versions section for the safe rollback path. Dapr 1.17.7 includes the dapr/kit PEM-decoder fix (dapr/dapr#9904) that makes 1.17.x forward-compatible with 1.18-issued bundles.

See Workload identity key algorithm in the security concepts for the full rationale, compatibility matrix, FIPS guidance, and the 1.17.7 downgrade floor. The operational view is in mTLS.

Component Improvements

Notable component highlights this cycle:

  • Configuration stores: New ConfigMap configuration store with both get and subscribe options (#4275) — for Dapr Agents this is valuable to hot-reload operator-led configurations; PostgreSQL fix to read pgNotifyChannel from component spec instead of requiring client code to pass it (#4241); Azure App Configuration surfaces contentType and label in metadata (#4338).
  • Pulsar pubsub: listenerName metadata field for advertisedListeners support, Avro schema registration on the CloudEvents envelope, JSON-payload validation against schema, Avro payload decoding on the subscribe path, and processMode async backpressure (#4244, #4266, #4302, #4305, #4309, #4386, and immediate-bulk-subscribe #4364).
  • Kafka pubsub: PausableSubscriber interface and graceful shutdown hardening (#4366), per-message partition support (#4298), bulk-flush ticker reset (#4378).
  • RabbitMQ pubsub: unique consumer tags to prevent subscription disruption on restart (#4326).
  • State stores: SQL Server native batched BulkGet for v2 (#4365), Oracle BulkGet chunking (#4341), MongoDB KeysLiker (#4278), CockroachDB image bump (#4291), RavenDB state store registered in the runtime (dapr/dapr#9654).
  • Bindings: Azure Blob Storage presign operation + bulk operations (#4299, #4295); AWS S3 bulk file transfer (#4292).
  • Conversation API: Anthropic on Microsoft Foundry (#4374), LLM model surfaced on response (#4331), error returned when required tool calls weren't made (#4277), Ollama endpoint metadata field (#4314).
  • TLS hardening: redis common no longer unconditionally skips TLS cert verification (#4261) — see changes below.

See the full per-repo PR list below for the rest.

SDK Improvements

Go SDK

The marquee feature is workflow history context propagation (#823): a workflow can hand a slice of its execution history to the child workflows and activities it schedules, instead of threading that state through inputs or a state store. Propagation is opt-in per call. A producer passes workflow.WithHistoryPropagation(workflow.PropagateLineage()) (full ancestor chain) or …PropagateOwnHistory() (own events only) to ctx.CallChildWorkflow(...) / ctx.CallActivity(...), and the consumer reads back through a typed API: ctx.GetPropagatedHistory() returns a *workflow.PropagatedHistory, then GetLastWorkflowByName(...).GetLastActivityByName(...) retrieves a completed result by name. A runnable workflow-history-propagation example ships with the SDK.

The Jobs API graduates to stable (#824). ScheduleJob, GetJob, and DeleteJob call the stable RPCs and fall back to alpha against older sidecars, so one SDK build works on both 1.17 and 1.18 with no code change. The *Alpha1 client methods are deprecated and now delegate to the stable ones; the service callback is now OnJobEvent, with OnJobEventAlpha1 kept for older sidecars.

Beyond those two, this release fixes gRPC endpoint parsing when a connection string is supplied without a DNS scheme, and aligns dependencies and security baselines: durabletask-go is bumped to v0.12.1, the runtime protos to v1.18.0-rc.4, and gRPC is updated to address CVE-2026-33186.

Version mapping: Go SDK v1.15 ships with Dapr 1.18.

.NET SDK

Since the v1.17.0 release of the Dapr runtime, the .NET SDK has continued to modularize around individual building blocks, introducing two new clients in their own NuGet packages: Dapr.SecretsManagement and Dapr.StateManagement for secret and state management operations, respectively. Beyond simply yielding smaller, more focused dependencies, splitting these clients out of DaprClient lets each package adopt more modern .NET practices and ship tooling (such as source generators, analyzers and code-fixes) tailored to its building block rather than being constrained by a single monolithic client.

This release also consolidates the Dapr.Workflow package. The separate Dapr.Workflow.Versioning and Dapr.Workflow.Analyzers packages are no longer required - both are now bundled into Dapr.Workflow itself. No refactoring is necessary, but you should remove the now-stale package references pointing to the since-deprecated packages.

Building on the automatic workflow registration introduced in v1.17, registration is now handled for both workflows and activities, meaning neither needs to be registered with dependency injection at startup as the SDK takes care of it for you. There is no need to immediately clear out your existing DI registration block when upgrading to 1.18, as the SDK will gracefully continue to accept manual and duplicate registrations, but as of this release such registration is entirely unnecessary.

Finally, this release ships several new analyzers that validate type consistency between workflow and activity inputs and outputs, surfacing mismatches at build time rather than at runtime.

Python SDK

This release of the Python SDK folds the durabletask-python project into the main SDK, so workflow primitives now ship in a single package with version alignment to the Dapr runtime. The MCP surface is now exposed through a dedicated workflow client, letting workflows orchestrate MCP tool calls without wiring up a separate MCP SDK.

Workflow history context propagation is available on both child workflows and activities, with opt-in scopes for the caller's own history or the full lineage; consumers retrieve the propagated history through a typed query API. Workflows and activities also accept Pydantic models as inputs, removing the previous need to hand-roll conversions.

This release also addresses several rough edges: the workflow gRPC connection now honors the standard API timeout environment variable, the default 60-second drain timeout has been removed, the maximum inbound gRPC message size is configurable via an environment variable, and workers wait indefinitely for the runtime to be ready instead of failing fast.

Bulk pub/sub is now supported, Python 3.14 is supported (with the last Python 3.9 vestiges removed), and the Jobs API graduates to stable alongside the runtime. The package layout has been simplified — unnecessary dev packages removed and version metadata centralized into a single file.

Java SDK

The most disruptive changes are at the build level. The minimum Java version is now 17 (#1721); Java 11 is no longer supported. The Spring Boot baseline moves from 3.4 to 3.5 (the root springboot.version goes from 3.4.13 to 3.5.12), with Spring Boot 4 supported in parallel so projects on either line are covered. The SDK also now publishes a dapr-sdk-bom artifact (#1722) you can import to keep every Dapr dependency on a single, consistent version.

On the workflow side, the headline is history context propagation (#1739), matching the other SDKs. A producer opts in per call with WorkflowTaskOptions.withHistoryPropagation(scope) (or the propagateLineage() / propagateOwnHistory() shortcuts) on child workflow and activity calls, where scope is a HistoryPropagationScope of LINEAGE or OWN_HISTORY. Consumers read back through WorkflowContext.getPropagatedHistory() and WorkflowActivityContext.getPropagatedHistory(), which return an Optional<PropagatedHistory> with typed lookups (by workflow name, app ID, or instance ID, then per-workflow drill-down to the last activity or child workflow). Workflows also gain a timer origin field (#1733) so external-event waits are visible from outside, and DurableTaskGrpcWorker now shuts down cleanly by breaking out of the gRPC worker loop instead of hanging (#1727).

For service invocation, the new DaprClient.invokeHttpClient(appId) factory (#1742) returns an SDK-native HTTP client preconfigured to call a target app, mirroring .NET's CreateInvokeHttpClient. It is the recommended successor to the now-deprecated invokeMethod APIs. Streaming subscriptions gain dead-letter topic support (#1746): subscribeToTopic now takes a deadLetterTopic to which failed messages are forwarded. There is also baggage support (#1659) and trace propagation in local observations (#1724).

On the testing side, the SDK migrated from Testcontainers 1.21.4 to 2.0.5 and from JUnit 4 to JUnit 5 (#1736).

JS SDK

This release is mostly about setting the groundwork to catch the SDK up to features recently introduced in other packages. Going forward, package versioning will indefinitely remain at major version 3, the minor version will track the Dapr runtime release and the patch value will reflect any mid-cycle SDK releases that don't have new runtime dependencies. Thus, as the 1.18 Dapr runtime is being release, this package releases as v3.18.0.

In the prior 3.17.0 release, CommonJS modules were inadvertently discontinued in favor of ESM as a side effect of overhauling the gRPC generators. This module-packaging change has been reverted and we have no plans to deprecate our reliance on CommonJS. Should that ever change, it will be advertised via these release notes well in advance.

The dapr-client package on NPM has been marked as deprecated for a while, but was still receiving updates, but version 3.6.1 will be the last release on that package. All updates going forward will be applied to @dapr/dapr going forward.

Workflow client methods have been renamed for nomenclature consistency with the other SDKs (e.g. "orchestrators" -> "workflows"). This is not a hard break for now. The old names remain as '@deprecated' aliases and will continue to work, with removal scheduled for the release of Dapr 1.20, so you can migrate at your own pace.

Rust SDK

With version v0.19.0 of the Rust SDK significant changes have been made towards general stability and alignment with the other SDKs including the initialisation of the client using EnvVars and also by arguments.

As of this release, Workflows support has been added bringing almost complete support for all the Dapr APIs/Building Blocks. Siginificant changes are expected to follow after more feedback to ensure that the developer experience is improved.

Breaking Changes / Deprecations

This SDK is still in alpha and with each release, there are usually breaking changes. In this release the MSRV (Minimum Supported Rust Version) has been bumped to 1.88 using Edition 2024.

Please migrate to the new client implementation as documented in the examples.

List of issues addressed in this release

Dapr Runtime

  • ADDED Implement actor APIs for gRPC 927
  • RESOLVED add replace to go.mod 8868
  • ADDED Support for Spread Constraints and strict affinity rules in Dapr Control Plane charts to ensure Quorum resilience. 9223
  • RESOLVED Promote Dapr Jobs API to Stable 9257
  • RESOLVED Version Skew: 1.16-1.17 9315
  • RESOLVED Doc: link to security tab 9356
  • FIXED feat: improve output message of ErrActorNoAddress by adding req.ActorKey() 9360
  • ADDED Sentry: Support Per Audience Token SVID 9381
  • RESOLVED Bump actions/checkout from 3 to 6 9418
  • ADDED Support for Kubernetes native sidecar containers 9422
  • RESOLVED Constrain loop event types with scoped sealed interfaces 9423
  • ADDED Sidecar Injector supports Native Sidecars 9450
  • RESOLVED Bump github.com/lestrrat-go/jwx/v2 from 2.0.21 to 2.1.6 9454
  • RESOLVED Feature Gate: WorkflowsRemoteActivityReminder 9456
  • RESOLVED components-contrib: fix redis no key 9476
  • RESOLVED Fix pubsub e2e flake 9478
  • RESOLVED diagridio/go-etcd-cron: v0.12.3 9489
  • RESOLVED Point backport action to a specific commit 9491
  • RESOLVED use latest from contrib 9496
  • ADDED [1.18] Add hard anti-affinity policy option for placement and scheduler 9498
  • RESOLVED fix(ollama): rm old workaround for ollama 9499
  • RESOLVED Cherrypick in 1.17 perf charts 9501
  • RESOLVED [FORWARD_PORT] :secretRef for configuration otel headers (#9399) 9523
  • RESOLVED Add .github/copilot-instructions.md for Copilot coding agent onboarding 9534
  • RESOLVED Integration: Breakup resiliency app tests 9544
  • RESOLVED chore: Use dapr-bot to create backport PRs 9547
  • RESOLVED make pubsub_azure_servicebus_queues stable 9550
  • RESOLVED Integration: basic termination test 9557
  • RESOLVED Update kit & contrib v17 9568
  • REFACTOR Operator: refactor update streams to loops 9570
  • RESOLVED fix(ci): fix gh api command in update-longhauls workflow 9571
  • RESOLVED Bump Go to 1.26.0 and fix golangci-lint modernize/prealloc failures 9573
  • REFACTOR hotreload: simplify disk loader triggers and move reconciler to event loop 9574
  • UPDATED Component hot reloading is now generally available 9577
  • ADDED daprds: Adds SIGHUP handler reloader 9579
  • RESOLVED Integration: build stablecomponents 9580
  • ADDED hotreload: Configuration, HTTPEndpoint, and Resiliency 9582
  • RESOLVED Stalled workflow retention deletion 9588
  • FIXED Unnecessary placement dissemination for daprd hosts with no actor types 9591
  • ADDED Allow wildcards for service account names 9596
  • ADDED Sentry: Use Ed25519 for X.509 certificate key generation 9598
  • RESOLVED Fix flaky TestStartInternalCallbackSpan sampling rate test 9599
  • RESOLVED release notes added Reset bulk subscribe timer 9603
  • CHORE Bump Go to 1.26.1 9608
  • RESOLVED Fix Broken Perf Test Suite 9609
  • FIXED fix: Replace deep proto.Clone with shallow copy in invoke method request/response 9610
  • RESOLVED test: fix flaky retryGRPCProxy test by avoiding codes.Canceled in multi-range scenario 9616
  • FIXED fix: Race condition causes scheduler jobs to fire multiple times during host reconnection 9617
  • FIXED fix: Prevent pub/sub messages from being NACKed during graceful shutdown 9619
  • RESOLVED test: fix flaky actor reminder e2e tests by polling instead of fixed sleep 9620
  • ADDED feat(helm): Add overrideBroadcastHostPort option to scheduler chart 9629
  • FIXED ci: fix excessive GitHub workflow token permissions 9631
  • FIXED Fix actor placement version check 9639
  • RESOLVED Fix version skew tests 9640
  • RESOLVED Release notes for #9606 9646
  • RESOLVED test: fix flaky placement version assertions after batched dissemination 9648
  • ADDED feat(comp): register ravendb state component 9654
  • RESOLVED Add RavenDB state store component to v1.17.2 release notes 9657
  • RESOLVED Integration: Fix workflow test race 9660
  • RESOLVED CoPilot: reduce top level review comment 9663
  • ADDED Added support for timer origins 9665
  • RESOLVED integration: increase timeouts in flaky integration tests 9671
  • RESOLVED Use shared workflows and actions 9683
  • ADDED feat(mcp): add init mcp server resource 9685
  • FIXED Scheduler fix fatal crash on server restart due to duplicate controller registration 9688
  • FIXED Fix placement connection and dissemination churn 9689
  • FIXED Scheduler: fix silent cron exit on quorum change under load 9696
  • RESOLVED Remove redundant version-skew patch for release-1.17 9700
  • ADDED Support glob service accounts 9704
  • RESOLVED Add --amend and --purge flags to docker manifest commands 9705
  • UPDATED Jobs API stable 9706
  • TEST Jobs API stable — perf tests 9711
  • RESOLVED fix cleanup with peerShared for actors tests 9714
  • TEST Add e2e test for scheduler quorum recovery after pod kill 9717
  • RESOLVED [Workflows] Context propagation 9721
  • ADDED [Workflows] Human in the Loop support 9722
  • RESOLVED [Workflows] History signing 9723
  • ADDED MCP Server support for Dapr APIs 9724
  • ADDED [Workflows] Access policy 9725
  • ADDED Migrate DurableTask repos into corresponding SDK repos 9726
  • FIXED Bulk subscribe + sync mode causes high unacked count 9727
  • FIXED dapr workflow list not working with MongoDB actor state store in 1.17 9728
  • ADDED workflow state management improvements (purge, archive) 9730
  • ADDED feat(mcp): add built-in mcp wf orchestration engine for mcpserver crd 9731
  • RESOLVED Cherry pick 9718 9737
  • UPDATED updates based on durabletask proto changes 9739
  • ADDED feat(mcp): add crd clientset for cli mcp cmd 9742
  • FIXED fix(placement): reuse existing hashMap in VirtualNodesCache.setHashes 9753
  • RESOLVED Fix version-skew for cross-app workflow tests 9756
  • RESOLVED fix flaky crossactivity workflow integration test 9757
  • FIXED Tolerate missing CRDs in operator informers 9765
  • RESOLVED CI: retry transient docker push and crane.Copy failures 9766
  • CHORE Go: Update to v1.26.2 9767
  • FIXED Workflow: Fix carry over events for ContinueAsNew 9769
  • FIXED Fix daprd sidecar placement dissemination timeout handling 9770
  • TEST Add tests for retry timers origin field 9771
  • ADDED Workflow: Adds global and per-name concurrency limits 9775
  • ADDED Add workflow history signing for tamper detection 9778
  • ADDED Scheduler: more metrics 9787
  • ADDED Runtime: adds jitter to scheduler & placement re-conns 9788
  • UPDATED Workflow: default WorkflowsRemoteActivityReminder true 9789
  • ADDED Workflows: Adds WorkflowAccessPolicy 9790
  • FIXED fix(pubsub): flush bulk subscribe batches immediately via drain-and-flush 9792
  • DOCS document changes in allowedServiceAccounts 9793
  • RESOLVED Version-Skew: fix 9794
  • ADDED [P1] Add workflow global and per-name concurrency limits 9796
  • RESOLVED Fix 'sucessful' typo in scheduler.proto comment 9798
  • RESOLVED Tests: flakes 9799
  • RESOLVED feat: add config map configuration store component 9801
  • SECURITY fix service invocation path traversal ACL bypass 9805
  • RESOLVED Add missing release notes 9806
  • RESOLVED Fix flaky memory check in dapr-standalone-validation 9808
  • RESOLVED Integration: fix more flakes 9809
  • ADDED wf history ctx propagation 9810
  • UPDATED hotreload: enable HotReload by default (GA) 9811
  • ADDED Actors: app-initiated gRPC stream for actor callbacks 9812
  • SECURITY fix: bump golang.org/x/image to v0.39.0 for GO-2026-4962 9815
  • UPDATED Widen liveness and tighten readiness probe defaults 9818
  • RESOLVED Integration: fix flakes for stream dep jobs 9819
  • RESOLVED Fix typo in multiple license headers 9821
  • RESOLVED Integration: Workflow: scheduler disk exhaustion tests 9823
  • FIXED Workflow: terminate tampered in-flight workflows 9825
  • FIXED Bulk subscribe batches messages up to maxMessagesCount or maxAwaitDurationMs, whichever comes first, and restarts the await-duration timer on every flush so leftover messages join the next pending batch with a fresh window. Components that declare pubsub.FeatureBulkSubscribeImmediate (Pulsar) take a flush-on-arrival path so each message is acked as soon as it arrives. 9826
  • ADDED Workflow: child workflow & activity attestation 9831
  • FIXED Workflow: Fix recursive cross-app purge and terminate 9832
  • ADDED placement: post-round coalesce window + stable scheduler reload 9837
  • REMOVED Remove MCPServerResource and WorkflowAccessPolicy feature gates 9838
  • RESOLVED fix: remove availability zone requirement from AKS test clusters 9840
  • FIXED workflow: gracefully stall on oversized payload 9847
  • CHORE go-etcd-cron: update to origin HEAD 9849
  • UPDATED WorkflowAccessPolicy: Extend to all workflow operations 9850
  • RESOLVED Integration: speed up tests 9854
  • UPDATED WorkflowAccessPolicy: pure allow-list with self-call exemption 9870
  • UPDATED Injector/Operator: use RSA keys for webhook serving certs 9873
  • FIXED Workflow: dedup duplicate completion events at the actor inbox 9875
  • FIXED fix(placement): always arm coalesce timer after round to fix dissemination race 9876
  • RESOLVED Integration: fix flaky tests via metadata-API polling and tuning 9877
  • FIXED fix: Proto files must have different java outer classname 9878
  • CHORE Update go-jose & OpenTelemetry 9882
  • ADDED Workflow: cryptographically verify history propagation 9890
  • ADDED Add start time to wf metadata 9898
  • RESOLVED docs: add 1.17.7 release note for RabbitMQ consumer tag fix 9926
  • RESOLVED Integration: stdio helper binary and move helpers. 9932
  • ADDED feat: add initContainers and extraContainers support to control plane Helm charts 9939
  • FIXED MCPServer: correct workflow actor refcount 9940
  • ADDED Add support for sub-second precision in reminders 9946
  • RESOLVED version-skew: Fix against 1.17 9953
  • REFACTOR refactor(mcp): replace hand-defined MCP proto types with upstream go-sdk types 9959
  • RESOLVED scheduler: reconnect on WatchHosts first-Recv error instead of tearing down daprd 9968
  • RESOLVED fix(ci): migrate e2e to westus 9971
  • FIXED Actors: gate Register/UnRegisterHosted on runtime init 9976
  • RESOLVED CI: run macOS tests natively on arm64 9979
  • RESOLVED getLast func names for workflow history propagation 9981
  • RESOLVED chore(ci): update vm sizes 9983
  • RESOLVED chore: Update durabletask-go and components-contrib 9992
  • RESOLVED Fix test flakes 9993
  • RESOLVED fix(ci): use Hyper-V Gen 1-compatible Windows VM size for AKS test pool 9994
  • RESOLVED fix: update Go SSH crypto dependency 9999
  • RESOLVED fix dep review: net 10003
  • RESOLVED docs: list new workflow payload size ratio metrics 10005
  • RESOLVED workflow: save inbox event before creating wake-up reminder 10008
  • RESOLVED tests: stabilize flaky CI tests 10013
  • RESOLVED github.com/dapr/kit: update 0.18.1 10014
  • RESOLVED fix critical vulns: bump durabletask-go to v0.12.1 and bump pgx 10015
  • RESOLVED Workflow: retentioner ignore not completed errors 10019
  • RESOLVED Dependency update: govulncheck 10020
  • RESOLVED fix(mcp): gate /healthz/outbound on mcpserver wf registration 10023
  • RESOLVED Use contrib v1.18.0-rc.1 and bump kit 10024
  • RESOLVED ci(e2e): rename Azure Key Vault resource in workflow 10030
  • RESOLVED ci: pin azure/login to v3 10034
  • RESOLVED feat: register nameformat nameresolution component 10038

Dapr CLI

  • FIXED Using an image registry no longer attempts to reach out over the network. 1575
  • CHORE use dapr v1.17.3 1598
  • CHORE Adds the shared workflows 1603
  • FIXED fix flaky standalone e2e by dropping "Exited App successfully" requirement 1605
  • CHORE chore: Fetch latest version from the image registry and not from github 1615
  • FIXED fix(ci): trigger CLI build after creating release tag 1626
  • FIXED fix: rename with proto changes 1629

Components

  • FIXED Bug in Dapr bulk pubsub with rabbitmq 3663
  • FIXED Trouble Generating SAS Token for Blob Storage 3817
  • UPDATED Oracle state store bulk querying improvements 4041
  • RESOLVED feat(pubsub/azure/servicebus/queues): add certification tests 4150
  • RESOLVED fix(nameresolution.aws.cloudmap): quote numeric example in metadata.yaml 4233
  • RESOLVED Component Metadata Bundle GHA Tweaking 4234
  • CHORE chore: Use dapr-bot to create backport PRs 4237
  • FIXED ci: Workflows running twice on merge to master 4240
  • FIXED fix(configuration): ensure postgresql configuration reads pgNotifyChannel from component spec instead of requiring client code passing it 4241
  • RESOLVED fix: Fix dynamodb state store stable test 4242
  • RESOLVED fix(state/oracledatabase): return per-key errors in BulkGet instead of HTTP 500 4243
  • FIXED fix(pubsub/pulsar): validate JSON messages against Avro schema before publishing 4244
  • ADDED feat: warn when multiple redis stream trim strategies are specified 4252
  • FIXED ci: Allow reruns of failing jobs in master 4260
  • SECURITY fix(common/redis): stop unconditionally skipping TLS certificate verification 4261
  • RESOLVED Update Kafka Sarama Client dependency 4264
  • FIXED fix(pubsub/pulsar): decode Avro binary payload on subscribe path 4266
  • FIXED fix(conversation): nil pointer dereference in langchaingokit LLM logger 4268
  • ADDED feat(config): add config map as configuration 4275
  • ADDED Connection pooling support for the Oracle state store component. 4276
  • FIXED return err if tool calls were not called when required 4277
  • FIXED Fix MongoDB state store to implement KeysLiker 4278
  • RESOLVED test(cassandra): fix port collision in certification tests 4284
  • CHORE fix(state/cockroachdb): update image from v21.2.3 to v23.2.29 4291
  • ADDED Bulk file transfer operations to AWS S3 binding 4292
  • ADDED Azure Blob Storage binding: add bulk operations 4295
  • ADDED pubsub/kafka: per message partition support 4298
  • ADDED bindings/azure/blobstorage: Adds presign 4299
  • ADDED feat(pubsub/pulsar): register CloudEvents envelope Avro schema with Pulsar Schema Registry 4302
  • FIXED fix(pubsub/pulsar): validate JSON schema payloads against schema definition using goavro codec 4305
  • ADDED fix(pubsub/pulsar): read processMode from component metadata and add async backpressure 4309
  • ADDED fwd port: ollama: add missing endpoint metadata field to spec (#4287) 4314
  • CHORE Use shared workflows 4315
  • FIXED fix(pubsub/rabbitmq): use unique consumer tags to prevent subscription disruption on restart 4326
  • RESOLVED [1.18] zeebe oauth support 4330
  • ADDED Expose LLM model on converse response 4331
  • FIXED fix(ci): create GitHub release with metadata bundle in create-release workflow 4333
  • UPDATED [1.18] Azure appconfig - include contentType and label in metadata 4338
  • ADDED feat(state/oracledatabase): add BulkGet chunking to avoid Oracle IN-list limit 4341
  • ADDED feat(state/oracledatabase): add BulkGet chunking to avoid Oracle IN-list limit 4351
  • ADDED Adds immediate bulk subscriptions to the Pulsar pubsub component 4364
  • ADDED feat(state/sqlserver): native batched BulkGet for v2 4365
  • ADDED feat(pubsub/kafka): add PausableSubscriber + harden graceful shutdown 4366
  • CHORE bump to go1.26 4372
  • RESOLVED chore: bump sarama to 1.48.0 4373
  • UPDATED Enable anthropic in microsoft foundry 4374
  • FIXED fix(pubsub/kafka): reset await ticker after count-based bulk flush 4378
  • RESOLVED fix(ci): update artifact transformations 4381
  • FIXED fix(tests): scope influxdb to v2.9 4382
  • ADDED listenerName metadata field to Pulsar pubsub component for advertisedListeners support. 4386
  • RESOLVED CI: fix tests 4389
  • RESOLVED version bumps: kit/dapr/go-sdk 4391

.NET SDK

General

  • ADDED Dapr.SecretsManagement package #1794 to split secret management into its own client
  • ADDED Dapr.StateManagement package #1806 to split state management into its own client
  • ADDED Rich backwards-compatibility support added to the SDK to better support runtime API maturation lifecycles #1816
  • ADDED Serializer refactored from Dapr.Workflow to Dapr.Common #1805 as a precursor to having common serialization across .NET SDK
  • ADDED Add optional parameter to configuration providers for non-blocking startup #1844
  • UPDATED Making DaprDefaults public #1845
  • FIXED Prevent race condition during GrpcProtocolHandler disposal #1798

Actors

  • ADDED UnloadStateAsync implementation #1750 to force actors to unload their currently cached in-memory state (no impact to persisted state). The next time GetStateAsync is called, the cache is repopulated as normal.

PubSub

  • FIXED Subscriber resilience: SubscribeAsync now throws DaprException when the sidecar is unavailable instead of failing silently #1803

Metadata

  • ADDED Added new Dapr.Metadata package for retrieving strongly typed data from the Dapr Metadata API #1846. To use, add Dapr.Metadata package from NuGet, register in DI with builder.Services.AddDaprMetadata() and simply inject IOptions<DaprMetadata>, IOptionsSnapshot<DaprMetadata> or IOptionsMonitor<DaprMetadata> and read the values out of the injected value.

Service Invocation

  • UPDATED InvokeMethodAsync family marked [Obsolete] aligning SDK with prior runtime guidance — recommended guidance is to use a native HTTP/gRPC client for service invocation #1698.

Jobs

  • UPDATED Jobs API marked stable #1804.
  • UPDATED Minimum-version tags adjusted to reflect broader test coverage (#1811).

Workflows

  • ADDED Workflow history context propagation (#1802)
  • UPDATED Combined Dapr.Workflow meta-project (#1822) and automatic workflow/activity registration (#1823) This means that there is no longer a need to install Dapr.Workflow.Versioning or Dapr.Workflow.Analyzers separately. All are bundled in the one Dapr.Workflow package, no refactoring necessary (though you might want to remove the stale packages).
  • UPDATED No longer logging connection closed exception when app closes #1841
  • UPDATED Use server-blocking WaitForInstance* RPCs instead of client polling #1843
  • ADDED Timer origins and backwards-compatible optional timers (#1790)
  • ADDED Add workflow analyzer diagnostics on versioning (#1815
  • ADDED Expose name on workflow state #1836
  • ADDED Support history propagation API #1825, #1833
  • FIXED Workflow patch ordering #1807, #1809
  • FIXED Trace propagation fix for downstream calls from workflow user activities #1808
  • FIXED Addressing "no such instance exists" errors #1818, #1812
  • FIXED Fix workflow trace correlation #1829
  • FIXED add missing FailureDetails property to proto converter #1831

Miscellaneous/Testing

  • ADDED Integration test project for Actors.Generators #1791.
  • ADDED Adding gRPC probe with HTTP/2 preface to eliminate some transient Unavailable errors during integration testing via Testcontainers #1821
  • UPDATED Stabilization of flaky integration tests #1813.
  • UPDATED CI script more accurately auto-detects valid Dapr runtime versions to support automatic N-2 validation #1810
  • REMOVED Removing deprecated analyzers/codefixes #1834

Java SDK

  • ADDED Add baggage support 1659
  • TEST chore: Add test to verify workflow reconnection logic 1692
  • UPDATED Use Java source code 17 for Dapr Java SDK 1.18 1694
  • UPDATED Use latest protobuf 1698
  • ADDED Publish a dapr-sdk-bom artifact 1720
  • CHORE chore: bump minimum Java version from 11 to 17 1721
  • ADDED feat: publish dapr-sdk-bom artifact for transitive dependency management 1722
  • ADDED Adding trace propagation to local observations 1724
  • FIXED fix(durabletask): detect shutdown and break gRPC worker loop 1727
  • ADDED Implement timer origin 1729
  • ADDED feat(durabletask): implement timer origin and backwards-compatible optional timers 1733
  • UPDATED feat: upgrade Testcontainers from 1.21.4 to 2.0.5 and migrate JUnit 4 to JUnit 5 1736
  • RESOLVED Add support for workflow history propagation 1737
  • ADDED feat: download attestation.proto and use Runtime 1.18.0-rc.3 1738
  • RESOLVED [Phase 1] Fix Flaky Integration Tests + Migrate some tests to Test Containers 1741
  • ADDED feat: add DaprClient.invokeHttpClient(appId) factory 1742
  • ADDED DaprClient.invokeHttpClient(appId) factory — an SDK-native HTTP client preconfigured for service invocation, mirroring .NET's CreateInvokeHttpClient and serving as the successor to the deprecated invokeMethod APIs. 1743
  • FIXED fix(release): install dapr-sdk-bom locally before bumping dapr-spring-bom 1744
  • ADDED Add support for dead-letter topics in streaming subscriptions 1746
  • RESOLVED fix: reset gRPC channel backoff between worker reconnect attempts 1757

Python SDK

General

  • REFACTOR durabletask-python merged into the SDK #963
  • ADDED Python 3.14 support and removal of remaining Python 3.9 vestiges #916
  • UPDATED Centralize versions into a single file and remove development builds #1020
  • UPDATED No 60s timeout by default #956; default drain_ongoing_call_timeout to None #1016
  • ADDED Configurable max inbound message size via DAPR_GRPC_MAX_INBOUND_MESSAGE_SIZE_BYTES #1024
  • ADDED Add aio module and update mypy configuration to include aio files #942
  • UPDATED Use single v* tags to release #970

Workflows

  • ADDED Workflow history context propagation #1025; align history propagation API with go-sdk #1047
  • ADDED Populate timer origin field #976
  • ADDED Pydantic model support on workflow and activity inputs #982
  • FIXED when-all error handling #978
  • FIXED Apply DAPR_API_TIMEOUT_SECONDS to workflow gRPC connections #954
  • UPDATED Worker waits indefinitely for start #983
  • FIXED Align workflow multi-app naming convention #932
  • REMOVED Deprecated workflow operations #943

MCP

  • ADDED Dapr MCP client #997
  • FIXED Retry connect calls on transient gRPC errors #1062

Pub/Sub

  • ADDED Bulk pub/sub support #915

Jobs

  • UPDATED Jobs API marked stable #1060

Miscellaneous/Testing

  • ADDED Integration tests on DaprClient responses #981
  • REFACTOR Remove Mechanical Markdown from examples validation #977
  • FIXED Fix CI build #979

JavaScript SDK

General

  • UPDATED docs(actors): add JSDoc for actor runtime models and state metadata 815
  • UPDATED Comprehensive JSDoc Annotations Added to All Public Interfaces 816
  • UPDATED docs(jsdoc): annotate exported type definitions 817
  • UPDATED docs(jsdoc): annotate client and server implementations 818
  • REMOVED Removing dapr-client from published builds 773
  • FIXED fix: correct types path in published package 806
  • UPDATED Update buf configuration to emit CommonJS modules instead of ESM 826

Workflow

  • UPDATED Renaming workflow methods for consistency with other SDKs 783

Documentation

  • RESOLVED Docs: only one Redis stream trimming strategy supported 5061
  • RESOLVED Updates resiliency of streaming HTTP Service Invocation 5068
  • RESOLVED docs(agents): update with v1.0 rcs out 5071
  • RESOLVED workflow: retention policy is not retroactive 5074
  • RESOLVED Workflow: wf purge --all-older-than --all-filter-status 5075
  • RESOLVED docs(pulsar): add CloudEvents schema wrapping, rawschema option, and processMode improvements 5084
  • RESOLVED chore: update Azure Static Web App base hostname to new account 5095
  • RESOLVED chore: fix Azure Static Web App staging URL region suffix 5096
  • RESOLVED chore: update Azure Static Web App to new instance 5097
  • RESOLVED revert: restore original Azure Static Web App configuration 5098
  • RESOLVED Fix duplicate archived_version key in hugo.yaml 5101
  • RESOLVED Documented allowedServiceAccounts 5105
  • RESOLVED Add OAuth configuration fields to Zeebe command and JobWorker binding 5106
  • RESOLVED docs(agents): add MistralChatClient to supported LLMs 5108
  • DOCS [1.18] Add docs for global and per-name workflow concurrency limits 5109
  • RESOLVED [1.18] WorkflowAccessPolicy 5114
  • RESOLVED 1.18 Add response metadata section for Azure App Configuration 5118
  • RESOLVED fix: correct broken ref shortcode link in 5126
  • RESOLVED Update filename numbering to match quickstarts/ on dapr-agents 5143
  • RESOLVED Revert "Documentation for native-sidecar (#5041)" 5146
  • RESOLVED Add Reo.dev and cookie banner 5147
  • RESOLVED docs(agents): document replay-aware logging for DurableAgent 5149
  • RESOLVED docs(outbox): document outboxInternalTopic metadata field 5155
  • RESOLVED fix gcp storage bucket binding docs 5157
  • RESOLVED Improve ASP.NET Core docs and reference NuGet library 5164
  • RESOLVED docs: Sentry Ed25519 workload identity keys 5181
  • RESOLVED docs: Clarify max-body-size applies to requests and responses 5186

Upgrading to Dapr 1.18

To upgrade to this release of Dapr, follow the steps below to ensure a smooth upgrade.

Local Machine / Self-hosted

Uninstall Dapr using the CLI you currently have installed. Note that this will remove the default $HOME/.dapr directory, binaries and all containers dapr_redis, dapr_placement and dapr_zipkin. Linux users need to run sudo if docker command needs sudo:

bash
dapr uninstall --all

Download the latest release from here and put the dapr binary in your PATH.

Once you have installed the CLI, run:

bash
dapr init --runtime-version=1.18

Wait for the update to finish, then ensure you are using the latest version of Dapr (1.18) with:

bash
$ dapr --version

CLI version: 1.18
Runtime version: 1.18

Kubernetes

Upgrading from previous version

You can perform zero-downtime upgrades using both Helm 3 and the Dapr CLI.

Upgrade using the CLI

Download the latest release from here and put the dapr binary in your PATH.

To upgrade Dapr, run:

dapr upgrade --runtime-version 1.18 -k

To upgrade with high availability mode:

dapr upgrade --runtime-version 1.18 --enable-ha=true -k

Wait until the operation is finished and check your status with dapr status -k.

Note: Make sure your deployments are restarted to pick the latest version of the Dapr sidecar.

Upgrade using Helm

To upgrade Dapr using Helm, run:

helm repo add dapr https://dapr.github.io/helm-charts/
helm repo update

helm upgrade dapr dapr/dapr --version 1.18 --namespace=dapr-system --wait

Wait until the operation is finished and check your status with dapr status -k.

Note: Make sure your deployments are restarted to pick the latest version of the Dapr sidecar.

Starting a fresh install on a cluster

See how to deploy Dapr on a Kubernetes cluster for a complete guide to installing Dapr on Kubernetes.

You can use Helm 3 to install Dapr:

helm repo add dapr https://dapr.github.io/helm-charts/
helm repo update

kubectl create namespace dapr-system

helm install dapr dapr/dapr --version 1.18 --namespace dapr-system --wait

Alternatively, you can use the latest version of CLI:

dapr init --runtime-version=1.18 -k
Post Installation

Verify the control plane pods are running and are healthy:

$ dapr status -k
  NAME                   NAMESPACE    HEALTHY  STATUS   REPLICAS  VERSION  AGE  CREATED
  dapr-sidecar-injector  dapr-system  True     Running  1         1.18   15s  2026-05-26 13:07.39
  dapr-sentry            dapr-system  True     Running  1         1.18   15s  2026-05-26 13:07.39
  dapr-operator          dapr-system  True     Running  1         1.18   15s  2026-05-26 13:07.39
  dapr-placement         dapr-system  True     Running  1         1.18   15s  2026-05-26 13:07.39
  dapr-scheduler         dapr-system  True     Running  1         1.18   15s  2026-05-26 13:07.39

After Dapr 1.18 has been installed, perform a rolling restart for your deployments to pick up the new version of the sidecar:

kubectl rollout restart deploy/<deployment-name>

Downgrading to Earlier Versions

[!warning] Do not roll back from 1.18 directly to 1.17.6 or earlier.

Dapr 1.18 introduces Ed25519 workload identity keys, and Sentry persists the Ed25519-keyed CA into the dapr-trust-bundle secret. Versions of Sentry before 1.17.7 cannot parse this bundle and will crash on startup with:

fatal: error creating CA: failed to get CA bundle:
failed to verify CA bundle: unsupported key type ed25519.PrivateKey

When Sentry is down, no new workload certificates can be issued; existing sidecars with unexpired certificates keep working, but any sidecar restart or certificate expiry will fail to obtain a new identity.

Compatibility matrix

FromToResult
1.181.17.7+✅ Safe. 1.17.7 backports the Ed25519 PEM-decoder fix (dapr/dapr#9904) so Sentry can read the 1.18 trust bundle as-is.
1.181.17.6 or earlier❌ Sentry crash-loops at startup. Do not attempt this rollback.
1.17.6 or earlier1.18✅ Safe. 1.18 Sentry accepts CSRs of any algorithm; existing ECDSA P-256 bundles are read transparently.

Safe rollback path

If you must downgrade below 1.17.7, go through 1.17.7 first:

  1. Roll the control plane back to 1.17.7 (which includes the Ed25519 parsing fix and is the earliest version that can read a 1.18-issued trust bundle).
  2. Allow Sentry to stabilise and confirm dapr status -k is healthy.
  3. From 1.17.7, downgrade to your target version. Note that you may want to first rotate the CA back to an algorithm the target version generates natively — see your Sentry CA rotation runbook.

Rolling back the control plane

Use Helm rollback (preferred) or re-install at the target version:

bash
# Helm: list revisions, then roll back to the desired one
helm history dapr -n dapr-system
helm rollback dapr <REVISION> -n dapr-system --wait

# Or pin a specific version
helm upgrade dapr dapr/dapr --version 1.17.7 --namespace dapr-system --wait

After the control plane is back, perform a rolling restart of your application Deployments so sidecars pick up the older injector image and re-issue their identities against the rolled-back Sentry.

What does NOT need to be rotated

Going 1.18 → 1.17.7 does not require manual CA rotation. The Ed25519-keyed bundle remains valid; 1.17.7 reads it, continues to issue new CSRs against the existing trust anchor, and ECDSA/RSA CSRs from 1.17.x sidecars are signed normally. Only re-rotate the CA if your downgrade target is below 1.17.7 or if your security posture requires it.

Breaking Changes

[!warning] Review carefully before upgrading

  • WorkflowsRemoteActivityReminder default-on. Cross-app workflow activity results are now delivered via Scheduler reminders by default. See dapr/docs#5128 and dapr/dapr#9789.
  • HotReload default-on. Components, Subscriptions, MCPServers, Configurations, HTTPEndpoints, Resiliencies, and WorkflowAccessPolicies are hot-reloaded by default. To restore the pre-1.18 behavior, disable the HotReload feature in the Dapr Configuration (spec.features with enabled: false). See dapr/dapr#9811.
  • Sidecar probe defaults changed. Liveness is more lenient (~230 s before kubelet restart); readiness is tighter (~3 s control-plane / ~5 s daprd). Custom Helm overrides may need re-tuning. See dapr/dapr#9818.
  • Workflow ID reuse semantics changed. The pre-1.18 workflow ID reuse policy has been removed; creating a workflow with an instance ID that already has an active instance now fails with a conflict error (an active workflow with ID '<id>' already exists) instead of silently overwriting or ignoring it. Callers that previously relied on the silent-overwrite or ignore behavior must adapt. See dapr/docs#5102.
  • Hop-by-hop headers stripped on service invocation. Standard hop-by-hop HTTP headers (Connection, Keep-Alive, Proxy-Authenticate, Transfer-Encoding, etc.) are now stripped during service invocation, per RFC 7230. Apps relying on these passing through must move to non-hop-by-hop equivalents. See dapr/docs#5172 and dapr/dapr#9759.
  • JS SDK: dapr-client removed. The standalone dapr-client npm package is no longer published. Consumers must move to the unified @dapr/dapr package. See dapr/js-sdk#773.
  • Java SDK: minimum Java version is now 17. The Dapr Java SDK no longer supports Java 11. See dapr/java-sdk#1721 and tracking issue #1694.
  • Rollback floor is 1.17.7. Dapr 1.18 writes an Ed25519-keyed CA into the trust bundle. Sentry versions before 1.17.7 cannot parse this bundle and will crash on startup. Operators downgrading from 1.18 must go through 1.17.7 (or later 1.17.x) before any further rollback. See the Downgrading to Earlier Versions section and dapr/dapr#9598 / #9904.

Deprecation Notices

  • Workflows: Workflow instance ID reuse removed. A workflow instance ID can no longer be reused once an instance with that ID exists in any state (running, completed, failed, terminated). To free up an instance ID, purge the existing workflow via the purge API or configure a workflow retention policy. dapr/dapr#9739
  • Java SDK: Spring Boot 3.4 and 3.5 deprecated. See dapr/java-sdk#1718.
  • Java SDK: invokeMethod APIs (deprecated). Use the new DaprClient.invokeHttpClient(appId) factory introduced in this release. See dapr/java-sdk#1743.
  • .NET SDK: service-invocation InvokeMethodAsync family marked [Obsolete]. Recommended guidance is to use a native HTTP or gRPC client for service invocation. See dapr/dotnet-sdk#1698.
  • JS SDK: workflow methods renamed. get / start / raise are renamed to getWorkflowState / scheduleNewWorkflow / raiseEvent for consistency with the other SDKs. The old names remain as deprecated aliases and continue to work, with removal scheduled for Dapr 1.20. See dapr/js-sdk#783.
  • Dapr Dashboard deprecated repository archived. The dapr/dashboard repo has been archived and is no longer maintained as it had drifted well behind daprd and the maintainers chose to wind it down rather than ship a stale UI. For a maintained alternative, see the Diagrid Dev Dashboard; otherwise use kubectl, the dapr CLI subcommands, or your observability stack (Grafana/Prometheus) to inspect Dapr state.