The Azure SDK team is pleased to announce our September 2026 client library releases.

16 packages released this month.

Stable Packages (4)

  • Azure Storage SAS

  • Storage - Blobs

  • Storage - Queues

  • Storage Common

Patch Updates (3)

  • Key Vault - Certificates

  • Key Vault - Keys

  • Key Vault - Secrets

Beta Packages (9)

  • Core

  • Core - AMQP

  • Core - OpenTelemetry

  • Cosmos DB

  • Cosmos DB Client Driver

  • Event Hubs

  • Identity

  • TypeSpec Client Core

  • TypeSpec Core

Release highlights

Azure Storage SAS 1.0.0 Changelog

Breaking Changes

  • Removed the UserDelegationKey re-export; import it from azure_storage_common::models directly.

Bugs Fixed

  • Fixed SAS generation for blob and directory paths containing backslashes by normalizing them to forward slashes in the signed resource.

Features Added

  • Stable release of features from 0.1.0

Core 1.2.0-beta.1 Changelog

Bugs Fixed

  • Updated typespec_client_core so dropping a sleep future created by the standard (non-tokio) async runtime promptly cancels its worker thread.

Features Added

  • Added Tracer::start_span_with_options, Tracer::start_span_with_parent_and_options, and Span::end_at, along with a SpanOptions struct, to allow reconstructing spans with explicit (backdated) start and end timestamps. These are additive with default implementations, so existing Tracer/Span implementations continue to work unchanged.
  • Added DeserializeWith::deserialize_from with a body-only default, allowing custom model decoders to inspect response headers without requiring serde deserialization.
  • Added cloneable stream::ReadStream and stream::SeekableReadStream adapters, along with RequestContent::from_reader and RequestContent::from_seekable_reader, to build request bodies from futures::io::AsyncRead sources.

Core - AMQP 1.2.0-beta.1 Changelog

Bugs Fixed

  • Link properties set through AmqpReceiverOptions::properties and AmqpSenderOptions::properties now reach the Attach frame. They were discarded before the link attached.
  • A failed receive now reports the link-state kind the sender path already reports: AmqpDescribedError when the remote closed or detached with an AMQP error, and LinkClosedByRemote or LinkDetachedByRemote otherwise. All of these previously reported LinkStateError.

Features Added

  • Added AmqpTransport and AmqpConnectionOptions::transport to support AMQP over secure WebSockets.
  • Added the fe2o3_amqp_ws and fe2o3_amqp_ws_rustls features for AMQP over WebSockets. Both are enabled by default.
  • Added the fe2o3_amqp_rustls feature for AMQP over TCP with rustls and the aws-lc-rs provider. It is enabled by default. (#4189)
  • Added AmqpReceiverApis::settle_delivery and AmqpDeliveryOutcome to settle deliveries with accepted, rejected, released, or modified outcomes. See #4935.
  • Added the AmqpErrorCondition::DeadLetter variant for the com.microsoft:dead-letter error condition. See #4935.

Breaking Changes

  • Added the transport field to AmqpConnectionOptions. Use struct update syntax with Default::default() when initializing the struct.
  • The default AMQP-over-TCP TLS backend changed from native-tls to rustls with the aws-lc-rs provider. The TLS connector uses the operating system trust store. (#4189)

Core - OpenTelemetry 1.1.0-beta.1 Changelog

Features Added

  • Implemented span backdating (Tracer::start_span_with_options, Tracer::start_span_with_parent_and_options, and Span::end_at) by mapping to the OpenTelemetry SpanBuilder::with_start_time and Span::end_with_timestamp APIs, so late-bound (tail-sampled) spans can be emitted with their original timestamps.

Cosmos DB 0.38.0 Changelog

Bugs Fixed

  • Fixed doubles losing up to 1 ULP when a text JSON response body is parsed, so a value such as 96.182417728091792 no longer comes back as 96.1824177280918. serde_json’s default float parser is not correctly rounded; the float_roundtrip feature is now enabled. (#5040)
  • Unsafe client-side PATCH operations now persist a bounded marker with the mutation, preventing duplicate increments, array edits, removes, and moves when a Replace commits but its response is lost. (#5173)
  • PatchOperation::Increment now serializes with the incr wire tag the Cosmos DB service expects, instead of increment. This is observable where patch instructions reach the service directly — today the distributed-transaction patch operation, whose increments were rejected. ContainerClient::patch_item is unaffected, as its read-modify-write loop never puts the instructions on the wire. Deserialization stays backward compatible: increment is still accepted on input, so persisted patch documents keep parsing, and re-serializing upgrades them to incr. (#5087)
  • ContainerProperties, IndexingPolicy, VectorEmbeddingPolicy, and VectorEmbedding now preserve container configuration this SDK version does not model. ContainerClient::replace serializes these types verbatim, so a read-modify-replace previously stripped anything unrecognized from containers created by another SDK or the portal. Unknown fields are now captured on read and written back on replace. (#5034)
  • DatabaseClient::read_throughput and begin_replace_throughput now reject a non-database RID (for example a container RID) with CLIENT_INVALID_RESOURCE_ID instead of silently reading or replacing that resource’s throughput offer. Throughput offers are keyed only by offerResourceId, so a DatabaseClient addressed by a container RID would otherwise operate on the container’s offer. (#4640)
  • The Cosmos tracing span’s operation label now prefers the caller-facing CosmosOperationContext identity over the driver-recorded name, matching how the db.operation.name metric attribute is resolved. Previously an aggregate whose surfaced sub-operation differed from the caller’s operation — such as a PATCH that fails during its internal read — could label the span read_item while the metric reported patch_item. Attempt spans now carry the operation that issued them, so a PATCH’s attempts report db.operation.name of patch_read_item / patch_replace_item while its operation span and metric stay patch_item; attempts of every other operation continue to inherit the operation’s own name. (#4874)

Breaking Changes

  • Cosmos binary JSON encoding is now enabled by default for supported item and query operations. Use CosmosClientBuilder::with_binary_encoding_options(BinaryEncodingOptions::new().with_enabled(false)) or set AZURE_COSMOS_BINARY_ENCODING_ENABLED=false to retain text JSON on the wire. (#5227)
  • ContainerClient::patch_item() and PatchItemOptions are now gated behind the new, non-default preview_patch feature while the API remains in preview. Enable preview_patch to keep using it. (#5133)
  • DatabaseClient::container_client now requires a second argument of type Option<ContainerClientOptions>; pass None to retain the previous behavior. (#4992)
  • CosmosClient::database_client and DatabaseClient::container_client now take impl Into<ResourceIdentity> instead of &str; call sites passing a deref-able string (for example a Cow<str> field) need &*value or .as_ref(). (#4687)
  • DatabaseClient::id() now returns &ResourceIdentity instead of &str. (#4687)
  • Control-plane APIs are now gated behind the new control_plane feature, which is not enabled by default. Code using database or container management (CosmosClient::create_database/query_databases, DatabaseClient::read/create_container/query_containers/delete, ContainerClient::replace/delete), throughput management (read_throughput/begin_replace_throughput, ThroughputPoller), or the associated model and options types (DatabaseProperties, ThroughputProperties, and the container create/replace/delete/query, database, and throughput option types) must now enable the control_plane feature. Reading container properties via ContainerClient::read() — along with ContainerProperties, IndexingPolicy, ResourceResponse, and ReadContainerOptions — remains available without the feature, since it works with Entra ID authentication and mirrors the metadata read the SDK already performs internally. (#4854)
  • Fresh cross-partition queries and change feed reads now fail with a BadRequest error if they would fan out to more than 100 physical partitions. Raise FeedOptions::max_fan_out to run a broader operation. The limit is checked only at initial query setup — resuming from a continuation token is unaffected, and a partition split that raises the fan-out mid-execution does not abort the operation. (#4855)

Features Added

  • Added preview PatchStrategy, PatchItemOptions::with_strategy, and PatchItemOptions::with_precondition; the default Auto strategy uses one server request for retry-safe lists of at most 10 instructions and client-side RMW otherwise, with marker-backed tracking only for non-retry-safe lists. (#5196)
  • Added PatchTrackingId, PatchInstructions::is_retry_safe, PatchItemOptions::with_tracking_id, PatchItemOptions::with_tracking_capacity, PatchItemOptions::with_tracking_retention_seconds, ItemResponse::patch_tracking_id, CosmosError::patch_tracking_id, FaultInjectionErrorType::ResponseTimeoutAfterService, and public PATCH tracking property, retention, and default-capacity constants for bounded duplicate suppression across application retries. (#5173)
  • Added CosmosClientBuilder::with_partition_key_range_cache_enabled to disable partition topology caching and /pkranges requests when only topology-independent operations are needed. (#5174)
  • Added ResourceId and ResourceIdentity for addressing Cosmos databases and containers by user-provided name or by RID. (#4687)
  • CosmosClient::database_client and DatabaseClient::container_client now accept impl Into<ResourceIdentity>, so a &str/String selects name addressing and a ResourceId selects RID addressing. (#4687)
  • Added DatabaseClient::name() and DatabaseClient::rid() to inspect how a database client was addressed. (#4687)
  • RID-addressed databases skip the extra database read when resolving throughput offers, reusing the addressed RID directly. (#4687)
  • Reading and querying items by RID now works end-to-end, including a parent-database cross-check that rejects a container RID belonging to a different database. (#4687)
  • Added cross-partition DISTINCT query support. SELECT DISTINCT now deduplicates structurally equal values across every physical partition and page, rather than failing as an unsupported query feature. A DISTINCT query of the exact form SELECT DISTINCT VALUE <path> … ORDER BY <same path> (for example SELECT DISTINCT VALUE c.city FROM c ORDER BY c.city) is resumable from a continuation token; every other shape — including a list projection such as SELECT DISTINCT c.city … and any multi-column ORDER BY — is not, and requesting a token for it returns an error explaining how to rewrite the query. (#5026)
  • Added an SDK-generated x-ms-client-id header that remains stable for each CosmosClient. (#4844)
  • Added opt-in Cosmos binary JSON encoding for item operations (create/read/replace/upsert). Enable it via CosmosClientBuilder::with_binary_encoding_options (or the AZURE_COSMOS_BINARY_ENCODING_ENABLED environment-variable fallback). Off by default; when disabled, requests and responses are byte-for-byte unchanged. (#4671)
  • Extended binary JSON encoding to query_items: when binary encoding is enabled, queries negotiate a binary response (the request body stays text application/query+json) and decode binary feed pages, including the streaming cross-partition ORDER BY merge. Off by default and negotiated on the standard-gateway path. (#5040)
  • Added FeedOptions::max_fan_out (and FeedOptions::with_max_fan_out) to cap how many physical partitions a cross-partition query or change feed may fan out to. Applies to ContainerClient::query_items and ContainerClient::query_change_feed. The cap is enforced only at initial query setup; a partition that splits mid-execution and pushes the fan-out higher does not abort the operation. (#4855)
  • Added resumable cross-partition streaming ORDER BY query support. (#4800)
  • Added a pluggable client-side diagnostics emission layer — the DiagnosticsHandler trait and ordered DiagnosticsHandlerChain (registered via CosmosClientBuilder::with_diagnostics_handler) — invoked once per operation (singleton and paginated, on success and failure) with the completed DiagnosticsContext plus an SDK-supplied CosmosOperationContext; the empty default chain is a zero-overhead no-op. (#4789)
  • Added the metrics-gated CosmosMetricsHandler (with MetricsOptions), emitting the stable db.client.operation.duration histogram plus per-signal opt-in metrics (with_request_charge_metric, with_returned_rows_metric) and an opt-in extended attribute set (with_extended_attributes); a no-op when no meter provider is registered. Each histogram declares explicit bucket boundaries (attributes::BUCKETS_OPERATION_DURATION_SECONDS, BUCKETS_REQUEST_CHARGE_RU, BUCKETS_RETURNED_ROWS) rather than inheriting OpenTelemetry’s millisecond-scaled defaults, which would collapse every real observation of the seconds-valued duration metric into a single bucket and make latency percentiles constant. (#4789)
  • Added MetricsOptions::with_active_instance_metric, an opt-in azure.cosmosdb.client.active_instance.count up-down counter reporting the number of live CosmosClient instances per account endpoint, keyed on server.address (plus server.port for a non-default port). (#4874)
  • Added DiagnosticsHandler::on_client_created, a defaulted hook that lets a handler observe client construction (CosmosClientInfo) and return a ClientLifetimeToken dropped with the client, for handlers that need to track client lifetime. (#4874)
  • Added composable tail-sampled emission handlers — a TracingLogHandler leaf that writes a compact tracing line and a SamplingLogHandler wrapper (holding an Arc<dyn DiagnosticsHandler>) that applies the sampling gate plus a shared per-window rate limit, defaulting to wrap a TracingLogHandler — and the distributed_tracing-gated CosmosTracingHandler (backdated span tree), also rate-limited so an error storm can’t overwhelm exporters. All emit only for operations which fail or breach a configurable DiagnosticsThresholds, and stamp why they were sampled (a failure, or which threshold) on the emitted line and span. (#4789)
  • Added the non-default control_plane feature that gates the control-plane APIs (database and container CRUD, and throughput/offer management). It is intentionally independent of key_auth so these APIs are not tied to key-based authentication. (#4854)
  • Added full text search policy support: the FullTextPolicy and FullTextPath models, ContainerProperties::full_text_policy (with with_full_text_policy), the FullTextIndex model, and IndexingPolicy::full_text_indexes (with with_full_text_index). Containers configured for full text search can now be created and read with this SDK instead of only through another SDK or the portal. (#5034)
  • Added the vector index tuning options the service accepts: VectorIndex::quantizer_type (the new QuantizerType enum), quantization_byte_size, indexing_search_list_size, and vector_index_shard_key, each with a matching with_* setter. (#5034)

Cosmos DB Client Driver 0.7.0 Changelog

Bugs Fixed

  • Fixed doubles losing up to 1 ULP when a text JSON body is parsed, so a value such as 96.182417728091792 no longer comes back as 96.1824177280918. serde_json’s default float parser is not correctly rounded; the float_roundtrip feature is now enabled. (#5040)
  • Literal % characters in resource names are now percent-encoded on the HTTP request path so the gateway resolves the intended resource while authorization continues to use the original name. (#5207)
  • Unsafe PATCH operations now atomically persist bounded tracking markers so ambiguous Replace retries and caller-token retries recognize their own prior commit instead of reapplying non-idempotent instructions. (#5173)
  • PATCH Read-Modify-Write reads now prefer the PPAF partition writer or account write endpoints, force ReadConsistencyStrategy::LatestCommitted without a session token, and suppress hedging so a future verification read cannot be won by a stale replica; when write routing is unavailable or excluded, the read falls back with account-default session semantics and records a routing_fallback request event when it uses a reader. (#5167)
  • Stored procedure execution is no longer retried when the outcome is ambiguous. docs/ErrorCodesAndRetries.md has always stated that stored procedures are excluded from write retries, but no such exclusion existed — an Execute operation was failed over across regions like any other write, so a procedure that had already run could be re-run and repeat its mutations. OperationType::Execute now aborts on 408, on 5xx other than 503, and on a transport error that was not definitively unsent. It still retries where the response proves the procedure did not run (503, 410, 429, 449, 403/3, 403/1008, and definitively-unsent transport errors). Non-idempotent writes such as Create and Upsert are still retried after an ambiguous failure, which remains a deliberate divergence from the other Cosmos DB SDKs. (#5111)
  • PatchOperation::Increment now serializes with the incr wire tag the Cosmos DB service expects, instead of increment. The tag is only observable where PatchInstructions reaches the service directly, which today is the distributed-transaction patch operation — a DTX patch containing an increment was rejected by the service. The client-side read-modify-write patch_item path is unaffected, because it deserializes the instructions back with the same codec and never puts them on the wire. Deserialization stays backward compatible: increment is still accepted on input, so patch documents persisted by earlier versions keep parsing, and re-serializing upgrades them to incr. (#5087)
  • The background endpoint-probe loop no longer probes endpoints the account has stopped advertising. Endpoint failback is owned exclusively by the connectivity-probe loop (there is no time-based expiry), so a mark for a region removed from the account was re-probed on every sweep — forever — against a hostname that is eventually withdrawn from DNS. The mark itself is deliberately retained rather than dropped: it is inert for routing while the region is absent, and keeping it means a region that returns to the account must still pass a probe before it takes live traffic. (#4993)
  • Name-based request paths whose leaf id contains a path-legal reserved character (for example an item id like Item@1) are no longer over-encoded. The driver previously percent-encoded every non-unreserved character in a name-based path, turning @ into %40; on Gateway 2.0 — which compares the outer HTTP path against the raw RNTBD target byte-for-byte — this produced a 400 outer-path/RNTBD mismatch. The driver now sets the URL path via Url::set_path, applying only the minimal RFC 3986 path percent-encoding, so path-legal characters (and the =/+ in a base64 RID) reach the gateway raw and match the resource link that was signed. (#4640)
  • Point operations addressed by name under a RID-addressed parent are now rejected client-side with CLIENT_MIXED_NAME_RID_ADDRESSING instead of being sent to the service. Cosmos classifies a request as name-based or RID-based from its dbs segment alone, so a RID-addressed path must be RID-addressed end to end; a name leaf (e.g. /dbs/{rid}/colls/{rid}/docs/{name}) was rejected by the service with an opaque 400 Failed to parse the value '{name}' as ResourceId. Feed-style operations are unaffected — Create and Upsert POST to the parent collection URL, so their item id never reaches the wire and remains legal by name. Address the leaf by RID (ItemReference::from_rid) to point-operate on a RID-addressed container. (#4640)
  • Addressing-consistency validation now rejects mixed addressing in both directions: a RID leaf under a name-addressed parent (e.g. /dbs/{name}/colls/{name}/docs/{rid}) is now rejected with CLIENT_MIXED_NAME_RID_ADDRESSING, matching the existing rejection of a name leaf under a RID-addressed parent. Such a request would otherwise sign the bare leaf RID against a name-routed URL and fail with an opaque gateway 401. (#4640)
  • Distributed transactions now reject a RID-addressed target container up front with a 400 BadRequest instead of serializing an empty databaseName into the transaction target. A RID-addressed ContainerReference carries no parent database name, and the DTX wire contract requires it, so a transaction routed through such a container would otherwise reach the coordinator with a malformed target. (#4640)
  • CosmosDriver::resolve_container_by_rid now rejects a RID whose decoded length is not exactly the 8 bytes of a container RID. A 16-byte document RID (or a 4-byte database RID) previously slipped through a >= 8 length check and was misrouted into the colls segment of a service request; it is now rejected up front with CLIENT_INVALID_RESOURCE_ID. (#4640)
  • Unified 403/3 and 403/1008 topology retries under a 5-second cumulative delay budget so a persistent topology error surfaces promptly instead of hanging. Multi-write 403/3 and all 403/1008 come down from ~120 seconds of fixed 1-second retries; single-write 403/3 moves up from three immediate generic retries onto the same topology policy. The first retry is always immediate; later retries use exponential backoff with jitter. (#4740)
  • DiagnosticsContext::operation_name() is now populated in production (previously always None): the operation pipeline sets it from CosmosOperation::db_operation_name, so tail-sampling classification and the tracing span have an operation name even when no SDK-supplied CosmosOperationContext is present. (#4874)
  • PATCH operations now report patch_item rather than the underlying Replace, on both the aggregated success path and every error path (including read, deserialize, patch-evaluation, serialize, and non-412 replace failures). The two internal sub-operations report patch_read_item and patch_replace_item on their own attempt diagnostics, so the read-modify-write decomposition stays visible underneath the caller-facing operation instead of being flattened to a single name. (#4874)
  • Fixed a partition-key-range refresh that could remain permanently pinned to an unreachable region. A refresh resuming a region-affine change-feed continuation is routed back to the region that served it, with hedging suppressed; if that region then became unavailable, every subsequent forced refresh repeated the same failing request forever. Such a refresh now retries once from cold, which clears both the continuation and the region pin together. The same clearing now also applies when an incremental routing-map merge falls back to a full refresh that comes back empty, which previously left the continuation in place after the pin protecting it had already been released. (#4896)
  • Fixed session-token parsing rejecting the version sentinel -1 (as in 0:-1#42). Merging such a token now succeeds and round-trips -1 verbatim. (#4800)

Breaking Changes

  • Cosmos binary JSON encoding is now enabled by default for supported item and query operations. Set OperationOptions::binary_encoding to Some(BinaryEncodingOptions::new().with_enabled(false)) to retain text JSON on the wire. (#5227)
  • CosmosDriver::resolve_all_partition_key_ranges and CosmosDriver::resolve_partition_key_ranges_for_key now return Result<Option<_>> so cache-disabled topology requests can return HTTP 400 with substatus 20159. (#5174)
  • Resource-reference accessors now return Option to account for RID-addressed references that have no name. DatabaseReference::name_based_path, ContainerReference::database_name, and ContainerReference::name_based_path return None when the reference is addressed by RID (previously they returned &str/String and assumed a name was always present). Use the new ContainerReference::base_path to obtain the addressing-appropriate path (RID-based or name-based) when building request URLs. (#4640)
  • AccountReference, DatabaseReference, ContainerReference, and ItemReference are now tuple structs wrapping private shared state, so wildcard struct patterns such as AccountReference { .. } no longer compile. All accessors are unchanged. DatabaseReference::into_account was removed; use DatabaseReference::account and clone. (#4908)
  • CosmosDriver::plan_operation now takes an additional plan_options: &PlanOptions argument (after continuation). The continuation token remains its own argument. (#4855)

Features Added

  • Added PatchStrategy (Auto, ClientSide, ServerSide) and server-side PATCH over standard Gateway and Gateway 2.0; Auto uses client-side RMW for unsafe lists or more than 10 instructions, while client-side-only settings do not influence strategy selection and explicit ServerSide surfaces the service limit and disables ambiguous retries for unsafe lists. (#5196)
  • Added PatchTrackingId, PatchInstructions::is_retry_safe, PATCH tracking capacity and whole-second retention controls, public tracking protocol constants, effective tracking ID access on responses, errors, and diagnostics, additive native v2 request/submit and completion-accessor support, and the ResponseTimeoutAfterService fault for testing commit-succeeded/response-lost recovery. (#5173)
  • Added DriverOptionsBuilder::with_partition_key_range_cache_enabled to disable partition topology caching and /pkranges requests; operations requiring physical topology return HTTP 400 with substatus 20159. (#5174)
  • Added CosmosOperation::allows_ambiguous_outcome_retry, reporting whether an operation may be retried when the request may already have been received and processed. It is false for stored procedure execution and unsafe explicit server-side PATCH; unlike is_idempotent it is true for Create and Upsert, matching the driver’s stance that non-idempotent writes are retried on purpose. Both retry layers now consult it, so the transport pipeline no longer refuses a same-endpoint shard retry for a failure the operation pipeline would immediately retry cross-region. (#5111)
  • Added binary round trip fuzzer. As a part of the implementation, binary JSON responses now deserialize a service-echoed integral Double into a signed or unsigned integer field (previously a type error); this is intentionally lossy for integers the service cannot represent exactly, while a fractional Double remains a type error. Does not yet cover integer elements inside a uniform Float64 array or an enum variant. (#4976)
  • Added driver-internal resolution of containers by resource id (RID). CosmosDriver::resolve_container_by_rid reads a container’s metadata addressing it purely by RID (deriving the parent database RID from the container RID, so no read_database round-trip is needed) and caches the result in a by-RID index. References are validated for consistent name/RID addressing in plan_operation — the single choke point every executable operation passes through, including multi-page queries — returning a deterministic CLIENT_MIXED_NAME_RID_ADDRESSING error before signing instead of letting the gateway reject a mixed name/RID request with an opaque 401. The new CLIENT_INVALID_RESOURCE_ID and CLIENT_MIXED_NAME_RID_ADDRESSING client statuses carry searchable names for diagnostics. (#4663)
  • Added models::is_database_rid, which reports whether a RID string decodes to a database-level RID (4 bytes). Lets callers that reuse a supplied RID as a database identity reject a wrong-hierarchy RID before it addresses the wrong resource. (#4640)
  • Added cross-partition DISTINCT query support (ordered and unordered), composed as a stage above the fan-out root and below any OFFSET/LIMIT/TOP window (so the row limit counts deduplicated values), and keyed on a structural, type-aware hash of the projected row, so structurally equal values collapse across partitions and pages. Ordered DISTINCT — only SELECT DISTINCT VALUE <path> … ORDER BY <same path>, the one shape the service reports as ordered; list projections and multi-column ORDER BY are unordered — is resumable, carrying only the last emitted hash in its continuation token. Unordered DISTINCT is not: OperationPlan::to_continuation_token fails with the new CosmosStatus::CLIENT_DISTINCT_CONTINUATION_UNSUPPORTED (HTTP 400) rather than returning a token whose resume would re-emit rows. A partition split that reaches the DISTINCT stage is refused with CosmosStatus::CLIENT_DISTINCT_CANNOT_FORWARD_SPLIT (HTTP 500) instead of being forwarded, since SplitRequired replaces the node that emits it and would discard the deduplication state. (#5026)
  • Added an SDK-generated x-ms-client-id header that remains stable for each CosmosDriver, including metadata, retry, hedge, probe, and Gateway 2.0 outer HTTP requests. (#4844)
  • Added a schema-agnostic Cosmos binary JSON codec (binary_json) and driver-side binary encoding via OperationOptions.binary_encoding (BinaryEncodingOptions). When enabled, the driver transcodes item request/response bodies between text and Cosmos binary JSON and negotiates the wire format; it is honored only for point Document item operations. Off by default and inert on the wire when unset. (#4671)
  • Extended binary response negotiation to Query/SqlQuery on Document: a query advertises a binary response while keeping its text request body, and every pipeline — passthrough, the streaming cross-partition ORDER BY merge, and OFFSET/LIMIT/TOP — carries binary pages through to the SDK’s integer-preserving deserializer. BinaryEncodingOptions::request_text_response is now honored for queries too, keeping the wire binary while handing back text rather than forfeiting negotiation. That text is re-serialized by the driver, not the service’s original bytes: values are preserved, but object keys come back sorted and numbers use Rust’s shortest round-trip rendering. Negotiation is honored on the standard-gateway path; the Gateway 2.0 / thin-client path does not yet carry the header. (#5040)
  • Added PlanOptions (with DEFAULT_MAX_FAN_OUT) to CosmosDriver::plan_operation, enforcing a maximum fan-out on fresh cross-partition plans. A fresh plan spanning more leaf request nodes than PlanOptions::max_fan_out (default 100) is rejected with the new CosmosStatus::CLIENT_CROSS_PARTITION_FAN_OUT_EXCEEDED (HTTP 400). The limit is enforced only at initial plan time: resuming from a continuation token skips the check, and a partition split that raises the fan-out mid-execution does not abort the operation. (#4855)
  • Added configurable HTTP/2 shard fan-out with atomic stream reservation, a 50% fan-out threshold relative to the 16-stream best-effort balancing threshold, and a CPU-scaled maximum connection default that applies the 32-connection floor only at four or more logical CPUs. (#4927)
  • Added CosmosOperation::db_operation_name, returning the canonical OpenTelemetry db.operation.name (e.g. read_item, query_items, execute_batch, and read_all_items_of_logical_partition for a read feed scoped to one logical partition) for an operation. (#4874)
  • Added RequestDiagnostics::operation_name, naming the operation that issued an individual attempt. It is set only where one DiagnosticsContext aggregates attempts from more than one operation — today a PATCH, whose attempts report patch_read_item / patch_replace_item while the context reports patch_item — and is None otherwise, meaning the attempt shares the context’s operation name. CosmosOperation::is_patch_sub_operation reports the same distinction on the operation itself. (#4874)
  • Extended cross-region hedging to the container and partition-key-range metadata reads, so a slow (but not failed) region no longer stalls a client’s first operation against a container. Metadata hedges use a fixed 1.5s threshold and never let a hedged region override a definitive primary result. (#4896)
  • Added HedgingOptions (via DriverOptionsBuilder::with_hedging_options), bounding how many metadata operations may make simultaneous cross-region attempts. Defaults to 32; 0 disables metadata hedging. An operation refused a slot follows the ordinary sequential failover path instead of queueing. Data-plane hedging is not budgeted — tracked by #4916. (#4896)
  • Added CosmosResponse::serving_region, returning the region that produced a response — the hedge winner when the operation raced, otherwise the region of the final attempt. (#4896)
  • Added resumable cross-partition streaming ORDER BY query support. (#4800)

Event Hubs 0.16.0 Changelog

Features Added

  • Added BufferedProducerClient, a producer that accepts single events and publishes them in the background. One worker owns each partition, so events keep their enqueued order and a slow partition does not stop the others. A successful enqueue means only that the local buffer accepted the event; the client reports each terminal outcome through the handlers that with_on_send_succeeded and with_on_send_failed register, and a handler for failed batches is required. The client sends a batch when the next event does not fit, when the batch reaches the configured event count, when the maximum wait time expires, on flush, and on close. The defaults are a 1 second maximum wait time and 1500 buffered events for each partition, matching the .NET, JavaScript, and Python clients. flush sets a barrier over the events accepted before the call, close sends the buffered events, and abort abandons them. The client reads the partition list one time, when it opens, so a partition that the service adds later stays unused until the application opens a new client. New public types: BufferedProducerClient, BufferedProducerClientBuilder, EnqueueEventOptions, SendBatchSucceededContext, and SendBatchFailedContext. (#4873)
  • Added the ErrorKind::SendNotAccepted error variant. The buffered producer reports an AMQP Modified or Released outcome as a delivery failure, because neither outcome means that the service durably stored the events. ProducerClient::send_batch keeps its historical behavior and treats both as success with a warning.
  • Added connection-string authentication. ProducerClientBuilder and ConsumerClientBuilder now have an open_with_connection_string method that authenticates with a Shared Access Signature parsed from an Event Hubs connection string (Endpoint=sb://...;SharedAccessKeyName=...;SharedAccessKey=..., optionally with EntityPath, or a pre-formed SharedAccessSignature). The connection-string parser is exposed publicly as ConnectionString. This reaches parity with the other Azure SDKs for development and test scenarios; Microsoft Entra ID via open with a TokenCredential remains the recommended path for production. The parser rejects empty required values and empty Event Hub names up front, and a pre-formed SharedAccessSignature reports its own se as the token expiry (rather than a rolling client-side window); because such a token cannot be renewed, the connection’s token refresher detects the non-advancing expiry and leaves the broker to enforce it. (#3459)
  • Added a with_transport builder method on ProducerClient and ConsumerClient, which takes the AmqpTransport of azure_core_amqp (re-exported as models::AmqpTransport). AmqpTransport::WebSocket tunnels AMQP over secure WebSockets (wss://, port 443), allowing clients to connect from networks that block the native AMQP ports (5671/5672). This matches the transport option offered by the .NET, Java, and Python Azure SDKs. The EventProcessor inherits the transport from the ConsumerClient passed to build, so it runs over WebSockets when that client selects them. (#3601)
  • Added the fe2o3_amqp, fe2o3_amqp_rustls, fe2o3_amqp_ws, and fe2o3_amqp_ws_rustls features, which forward the matching features of azure_core_amqp. The default feature selects the AMQP backend and the rustls stack with the aws-lc-rs provider for both the TCP and the WebSocket transport. That is the stack that the rest of sdk/core uses. See Breaking Changes for the effect on the TCP transport, which ran on native-tls before. To build on another stack, turn off the default features, name the base features, and take a direct dependency on fe2o3-amqp and fe2o3-amqp-ws with the stack you want; Cargo unifies the features. samples/list_blobs_native_tls shows the same pattern for reqwest.
  • Added the ErrorKind::InvalidBatchSize { requested, max_allowed } error variant. create_batch reports it when EventDataBatchOptions::max_size_in_bytes is zero or is larger than the maximum the sender link allows, so a caller can branch on the kind instead of the message. This matches the ArgumentOutOfRangeException that .NET raises and the typed error that Go returns for the same input.
  • Added the ErrorKind::MissingCheckpointMetadata { partition_id } error variant. PartitionClient::update_checkpoint reports it when the event carries no offset and no sequence number, so a caller can branch on the kind instead of the message. This matches the InvalidOperationException that .NET raises for the same input.

Bugs Fixed

  • ProducerClient::close now stops the authorization refresh task, so repeated producer life cycles release task-held memory. (#4595)
  • ConsumerClient::close and ProducerClient::close now close the connection when another object still holds it, most often an EventReceiver that the caller has not dropped. Both methods used to report an error and leave the connection open. (#4931)
  • A handle that outlives the client it came from now reports that the client is closed on its next call. Such a handle opened a second connection to the service before. (#4931)
  • EventProcessor::close now continues past a partition client that the application still holds. It used to stop there, which left the partition clients behind it open and skipped the close of the consumer client. (#4931)
  • Claims-based-security authorizations for one connection now run in sequence. The service permits one $cbs link for each connection, so a client that attached more than one link at once could fail with NotAllowed.
  • EventDataBatchOptions::max_size_in_bytes now takes effect. A batch keeps the requested size, and create_batch reports an error when the request is zero or is larger than the sender link allows.
  • A partition stolen by a higher-or-equal-epoch attacher now surfaces as ErrorKind::ConsumerDisconnected when the broker reports amqp:link:stolen on a re-attach, not only on an in-flight receive. Other attach failures inside the receive loop now classify by their own kind. The wrapper reported all of them as a message error, which the retry decider treated as non-retryable.
  • Fixed a deadlock when a CBS failure during management-client creation started connection recovery. (#4728)
  • Closed a stale-resource window in connection recovery. A ReconnectConnection recovery that fired while a slow-path attach (authorize, session begin, or sender/receiver link attach) was in flight could cache a resource bound to the just-dropped connection; the next operation on that resource failed (unauthorized / detached / closed) and triggered a second, redundant recovery cycle. A recovery generation counter now tags each cached resource, and a slow path that completes across a recovery discards its result and re-attaches against the new connection instead of caching the stale one. The authorizer’s token cache is mutable (a background task refreshes tokens) so it cannot use the same one-shot cell as the connection caches; both of its writers, authorize_path and the refresh task, instead re-check the generation under the same lock that recovery’s clear takes, and a recovery brackets its invalidation with a generation bump on each side, which leaves the counter odd for as long as the recovery runs, so a slow path that overlaps a recovery at either end also discards rather than caching a resource bound to the connection that recovery is dropping. A token refresh pass that a recovery discards now applies the same backoff floor as a failed pass, so a recovery storm cannot turn the refresh loop into an uncapped stream of credential and CBS calls. The per-path / per-partition concurrency is preserved. (#4454)
  • The error that a receive timeout produces now carries its cause unboxed, so downcast_ref::<std::io::Error>() returns the std::io::Error with ErrorKind::TimedOut. The cause was boxed twice, which stored a Box<std::io::Error> and made every downcast to std::io::Error return None. (#5098)
  • InMemoryCheckpointStore now rotates the ETag and refreshes last_modified_time when an existing ownership is renewed, matching the create path and the production BlobCheckpointStore. Previously the renewal path reinserted the caller’s record verbatim, leaving a stale ETag and timestamp; that divergence from the real store could mask bugs in code that relies on ETag rotation for optimistic concurrency. (#4594)
  • PartitionClient::update_checkpoint no longer reports success without writing a usable checkpoint. It wrote nothing when the event had no message annotations, and it wrote an empty checkpoint when the annotations held no position. An empty checkpoint suppressed the per-partition start position the caller configured. It also erased a good checkpoint in BlobCheckpointStore, because that store rewrites the whole blob metadata on each update. (#5097)

Breaking Changes

  • The default feature now selects fe2o3_amqp_rustls, so AMQP framed directly on TCP (amqps://, port 5671) runs on rustls with the aws-lc-rs provider where it ran on native-tls. Both stacks read the trust store of the operating system, so a namespace behind a private or an enterprise certificate authority keeps working. The stacks read that store through different platform APIs, and a deployment that tunes native-tls directly, such as one that sets OpenSSL environment variables, can still see a difference. To keep native-tls, turn off the default features, name fe2o3_amqp, and take a direct dependency on fe2o3-amqp with its native-tls feature. (#4189)
  • PartitionClient::update_checkpoint now returns an error when the event carries no offset and no sequence number. Such a call returned Ok(()) and recorded no position before.

Identity 1.1.0-beta.1 Changelog

Features Added

  • Added support for Arc-connected servers when using the ManagedIdentityCredential.
  • Added opt-in Azure Kubernetes Service identity binding support to WorkloadIdentityCredentialOptions through enable_proxy.

Key Vault - Certificates 1.0.1 Changelog

Bugs Fixed

  • Fixed the challenge authentication policy to cache the challenge scope only after the challenge resource is verified, so that a rejected challenge is not cached and reused by subsequent requests.

Key Vault - Keys 1.0.1 Changelog

Bugs Fixed

  • Fixed the challenge authentication policy to cache the challenge scope only after the challenge resource is verified, so that a rejected challenge is not cached and reused by subsequent requests.

Key Vault - Secrets 1.0.1 Changelog

Bugs Fixed

  • Fixed the challenge authentication policy to cache the challenge scope only after the challenge resource is verified, so that a rejected challenge is not cached and reused by subsequent requests.

Storage - Blobs 1.1.0 Changelog

Features Added

  • Stable release of features from 1.1.0-beta.1 and 1.1.0-beta.2

Storage - Queues 1.1.0 Changelog

Features Added

  • Stable release of features from 1.1.0-beta.1

Storage Common 1.0.0 Changelog

Features Added

  • Stable release of features from 0.1.0

TypeSpec Client Core 1.2.0-beta.1 Changelog

Bugs Fixed

  • Dropping a sleep future created by the standard (non-tokio) async runtime now cancels its worker thread immediately instead of leaving it blocked until the original deadline.

Features Added

  • Added Tracer::start_span_with_options, Tracer::start_span_with_parent_and_options, and Span::end_at, along with a SpanOptions struct, to allow reconstructing spans with explicit (backdated) start and end timestamps. These are additive with default implementations, so existing Tracer/Span implementations continue to work unchanged.
  • Added DeserializeWith::deserialize_from with a body-only default, allowing custom model decoders to inspect response headers without requiring serde deserialization.
  • Added cloneable stream::ReadStream and stream::SeekableReadStream adapters, along with RequestContent::from_reader and RequestContent::from_seekable_reader, to build request bodies from futures::io::AsyncRead sources.

TypeSpec Core 1.2.0-beta.1 Changelog

Bugs Fixed

  • Added azure-deprecating to the default allowed HTTP header list so shared debug and logging paths stop redacting it.

Latest Releases

View all the latest versions of Rust crates here.

Installation Instructions

To install any of our crates, copy and paste the following commands into a terminal:

$> cargo add azure_core@1.2.0-beta.1
$> cargo add azure_core_amqp@1.2.0-beta.1
$> cargo add azure_core_opentelemetry@1.1.0-beta.1
$> cargo add azure_data_cosmos@0.38.0
$> cargo add azure_data_cosmos_driver@0.7.0
$> cargo add azure_identity@1.1.0-beta.1
$> cargo add azure_messaging_eventhubs@0.16.0
$> cargo add azure_security_keyvault_certificates@1.0.1
$> cargo add azure_security_keyvault_keys@1.0.1
$> cargo add azure_security_keyvault_secrets@1.0.1
$> cargo add azure_storage_blob@1.1.0
$> cargo add azure_storage_common@1.0.0
$> cargo add azure_storage_queue@1.1.0
$> cargo add azure_storage_sas@1.0.0
$> cargo add typespec@1.2.0-beta.1
$> cargo add typespec_client_core@1.2.0-beta.1

Feedback

If you have a bug or feature request for one of the libraries, please post an issue to GitHub.