Azure SDK for Rust (September 2026)
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
UserDelegationKeyre-export; import it fromazure_storage_common::modelsdirectly.
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_coreso 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, andSpan::end_at, along with aSpanOptionsstruct, to allow reconstructing spans with explicit (backdated) start and end timestamps. These are additive with default implementations, so existingTracer/Spanimplementations continue to work unchanged. - Added
DeserializeWith::deserialize_fromwith a body-only default, allowing custom model decoders to inspect response headers without requiring serde deserialization. - Added cloneable
stream::ReadStreamandstream::SeekableReadStreamadapters, along withRequestContent::from_readerandRequestContent::from_seekable_reader, to build request bodies fromfutures::io::AsyncReadsources.
Core - AMQP 1.2.0-beta.1 Changelog
Bugs Fixed
- Link properties set through
AmqpReceiverOptions::propertiesandAmqpSenderOptions::propertiesnow 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:
AmqpDescribedErrorwhen the remote closed or detached with an AMQP error, andLinkClosedByRemoteorLinkDetachedByRemoteotherwise. All of these previously reportedLinkStateError.
Features Added
- Added
AmqpTransportandAmqpConnectionOptions::transportto support AMQP over secure WebSockets. - Added the
fe2o3_amqp_wsandfe2o3_amqp_ws_rustlsfeatures for AMQP over WebSockets. Both are enabled by default. - Added the
fe2o3_amqp_rustlsfeature for AMQP over TCP with rustls and the aws-lc-rs provider. It is enabled by default. (#4189) - Added
AmqpReceiverApis::settle_deliveryandAmqpDeliveryOutcometo settle deliveries with accepted, rejected, released, or modified outcomes. See #4935. - Added the
AmqpErrorCondition::DeadLettervariant for thecom.microsoft:dead-lettererror condition. See #4935.
Breaking Changes
- Added the
transportfield toAmqpConnectionOptions. Use struct update syntax withDefault::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, andSpan::end_at) by mapping to the OpenTelemetrySpanBuilder::with_start_timeandSpan::end_with_timestampAPIs, 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.182417728091792no longer comes back as96.1824177280918.serde_json’s default float parser is not correctly rounded; thefloat_roundtripfeature 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::Incrementnow serializes with theincrwire tag the Cosmos DB service expects, instead ofincrement. This is observable where patch instructions reach the service directly — today the distributed-transaction patch operation, whose increments were rejected.ContainerClient::patch_itemis unaffected, as its read-modify-write loop never puts the instructions on the wire. Deserialization stays backward compatible:incrementis still accepted on input, so persisted patch documents keep parsing, and re-serializing upgrades them toincr. (#5087) -
ContainerProperties,IndexingPolicy,VectorEmbeddingPolicy, andVectorEmbeddingnow preserve container configuration this SDK version does not model.ContainerClient::replaceserializes 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_throughputandbegin_replace_throughputnow reject a non-database RID (for example a container RID) withCLIENT_INVALID_RESOURCE_IDinstead of silently reading or replacing that resource’s throughput offer. Throughput offers are keyed only byofferResourceId, so aDatabaseClientaddressed 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
CosmosOperationContextidentity over the driver-recorded name, matching how thedb.operation.namemetric 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 spanread_itemwhile the metric reportedpatch_item. Attempt spans now carry the operation that issued them, so a PATCH’s attempts reportdb.operation.nameofpatch_read_item/patch_replace_itemwhile its operation span and metric staypatch_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 setAZURE_COSMOS_BINARY_ENCODING_ENABLED=falseto retain text JSON on the wire. (#5227) -
ContainerClient::patch_item()andPatchItemOptionsare now gated behind the new, non-defaultpreview_patchfeature while the API remains in preview. Enablepreview_patchto keep using it. (#5133) -
DatabaseClient::container_clientnow requires a second argument of typeOption<ContainerClientOptions>; passNoneto retain the previous behavior. (#4992) -
CosmosClient::database_clientandDatabaseClient::container_clientnow takeimpl Into<ResourceIdentity>instead of&str; call sites passing a deref-able string (for example aCow<str>field) need&*valueor.as_ref(). (#4687) -
DatabaseClient::id()now returns&ResourceIdentityinstead of&str. (#4687) - Control-plane APIs are now gated behind the new
control_planefeature, 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 thecontrol_planefeature. Reading container properties viaContainerClient::read()— along withContainerProperties,IndexingPolicy,ResourceResponse, andReadContainerOptions— 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
BadRequesterror if they would fan out to more than 100 physical partitions. RaiseFeedOptions::max_fan_outto 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, andPatchItemOptions::with_precondition; the defaultAutostrategy 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_enabledto disable partition topology caching and/pkrangesrequests when only topology-independent operations are needed. (#5174) - Added
ResourceIdandResourceIdentityfor addressing Cosmos databases and containers by user-provided name or by RID. (#4687) -
CosmosClient::database_clientandDatabaseClient::container_clientnow acceptimpl Into<ResourceIdentity>, so a&str/Stringselects name addressing and aResourceIdselects RID addressing. (#4687) - Added
DatabaseClient::name()andDatabaseClient::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
DISTINCTquery support.SELECT DISTINCTnow deduplicates structurally equal values across every physical partition and page, rather than failing as an unsupported query feature. ADISTINCTquery of the exact formSELECT DISTINCT VALUE <path> … ORDER BY <same path>(for exampleSELECT DISTINCT VALUE c.city FROM c ORDER BY c.city) is resumable from a continuation token; every other shape — including a list projection such asSELECT DISTINCT c.city …and any multi-columnORDER 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-idheader that remains stable for eachCosmosClient. (#4844) - Added opt-in Cosmos binary JSON encoding for item operations (
create/read/replace/upsert). Enable it viaCosmosClientBuilder::with_binary_encoding_options(or theAZURE_COSMOS_BINARY_ENCODING_ENABLEDenvironment-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 textapplication/query+json) and decode binary feed pages, including the streaming cross-partitionORDER BYmerge. Off by default and negotiated on the standard-gateway path. (#5040) - Added
FeedOptions::max_fan_out(andFeedOptions::with_max_fan_out) to cap how many physical partitions a cross-partition query or change feed may fan out to. Applies toContainerClient::query_itemsandContainerClient::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 BYquery support. (#4800) - Added a pluggable client-side diagnostics emission layer — the
DiagnosticsHandlertrait and orderedDiagnosticsHandlerChain(registered viaCosmosClientBuilder::with_diagnostics_handler) — invoked once per operation (singleton and paginated, on success and failure) with the completedDiagnosticsContextplus an SDK-suppliedCosmosOperationContext; the empty default chain is a zero-overhead no-op. (#4789) - Added the
metrics-gatedCosmosMetricsHandler(withMetricsOptions), emitting the stabledb.client.operation.durationhistogram 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-inazure.cosmosdb.client.active_instance.countup-down counter reporting the number of liveCosmosClientinstances per account endpoint, keyed onserver.address(plusserver.portfor a non-default port). (#4874) - Added
DiagnosticsHandler::on_client_created, a defaulted hook that lets a handler observe client construction (CosmosClientInfo) and return aClientLifetimeTokendropped with the client, for handlers that need to track client lifetime. (#4874) - Added composable tail-sampled emission handlers — a
TracingLogHandlerleaf that writes a compacttracingline and aSamplingLogHandlerwrapper (holding anArc<dyn DiagnosticsHandler>) that applies the sampling gate plus a shared per-window rate limit, defaulting to wrap aTracingLogHandler— and thedistributed_tracing-gatedCosmosTracingHandler(backdated span tree), also rate-limited so an error storm can’t overwhelm exporters. All emit only for operations which fail or breach a configurableDiagnosticsThresholds, and stamp why they were sampled (a failure, or which threshold) on the emitted line and span. (#4789) - Added the non-default
control_planefeature that gates the control-plane APIs (database and container CRUD, and throughput/offer management). It is intentionally independent ofkey_authso these APIs are not tied to key-based authentication. (#4854) - Added full text search policy support: the
FullTextPolicyandFullTextPathmodels,ContainerProperties::full_text_policy(withwith_full_text_policy), theFullTextIndexmodel, andIndexingPolicy::full_text_indexes(withwith_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 newQuantizerTypeenum),quantization_byte_size,indexing_search_list_size, andvector_index_shard_key, each with a matchingwith_*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.182417728091792no longer comes back as96.1824177280918.serde_json’s default float parser is not correctly rounded; thefloat_roundtripfeature 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::LatestCommittedwithout 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 arouting_fallbackrequest event when it uses a reader. (#5167) - Stored procedure execution is no longer retried when the outcome is ambiguous.
docs/ErrorCodesAndRetries.mdhas always stated that stored procedures are excluded from write retries, but no such exclusion existed — anExecuteoperation 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::Executenow aborts on408, on5xxother than503, 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 asCreateandUpsertare still retried after an ambiguous failure, which remains a deliberate divergence from the other Cosmos DB SDKs. (#5111) -
PatchOperation::Incrementnow serializes with theincrwire tag the Cosmos DB service expects, instead ofincrement. The tag is only observable wherePatchInstructionsreaches 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-writepatch_itempath is unaffected, because it deserializes the instructions back with the same codec and never puts them on the wire. Deserialization stays backward compatible:incrementis still accepted on input, so patch documents persisted by earlier versions keep parsing, and re-serializing upgrades them toincr. (#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 a400outer-path/RNTBD mismatch. The driver now sets the URL path viaUrl::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_ADDRESSINGinstead of being sent to the service. Cosmos classifies a request as name-based or RID-based from itsdbssegment 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 opaque400 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 withCLIENT_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 gateway401. (#4640) - Distributed transactions now reject a RID-addressed target container up front with a
400 BadRequestinstead of serializing an emptydatabaseNameinto the transaction target. A RID-addressedContainerReferencecarries 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_ridnow 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>= 8length check and was misrouted into thecollssegment of a service request; it is now rejected up front withCLIENT_INVALID_RESOURCE_ID. (#4640) - Unified
403/3and403/1008topology retries under a 5-second cumulative delay budget so a persistent topology error surfaces promptly instead of hanging. Multi-write403/3and all403/1008come down from ~120 seconds of fixed 1-second retries; single-write403/3moves 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 alwaysNone): the operation pipeline sets it fromCosmosOperation::db_operation_name, so tail-sampling classification and the tracing span have an operation name even when no SDK-suppliedCosmosOperationContextis present. (#4874) - PATCH operations now report
patch_itemrather 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 reportpatch_read_itemandpatch_replace_itemon 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 in0:-1#42). Merging such a token now succeeds and round-trips-1verbatim. (#4800)
Breaking Changes
- Cosmos binary JSON encoding is now enabled by default for supported item and query operations. Set
OperationOptions::binary_encodingtoSome(BinaryEncodingOptions::new().with_enabled(false))to retain text JSON on the wire. (#5227) -
CosmosDriver::resolve_all_partition_key_rangesandCosmosDriver::resolve_partition_key_ranges_for_keynow returnResult<Option<_>>so cache-disabled topology requests can return HTTP400with substatus20159. (#5174) - Resource-reference accessors now return
Optionto account for RID-addressed references that have no name.DatabaseReference::name_based_path,ContainerReference::database_name, andContainerReference::name_based_pathreturnNonewhen the reference is addressed by RID (previously they returned&str/Stringand assumed a name was always present). Use the newContainerReference::base_pathto obtain the addressing-appropriate path (RID-based or name-based) when building request URLs. (#4640) -
AccountReference,DatabaseReference,ContainerReference, andItemReferenceare now tuple structs wrapping private shared state, so wildcard struct patterns such asAccountReference { .. }no longer compile. All accessors are unchanged.DatabaseReference::into_accountwas removed; useDatabaseReference::accountand clone. (#4908) -
CosmosDriver::plan_operationnow takes an additionalplan_options: &PlanOptionsargument (aftercontinuation). 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;Autouses client-side RMW for unsafe lists or more than 10 instructions, while client-side-only settings do not influence strategy selection and explicitServerSidesurfaces 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 theResponseTimeoutAfterServicefault for testing commit-succeeded/response-lost recovery. (#5173) - Added
DriverOptionsBuilder::with_partition_key_range_cache_enabledto disable partition topology caching and/pkrangesrequests; operations requiring physical topology return HTTP400with substatus20159. (#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 isfalsefor stored procedure execution and unsafe explicit server-side PATCH; unlikeis_idempotentit istrueforCreateandUpsert, 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
Doubleinto a signed or unsigned integer field (previously a type error); this is intentionally lossy for integers the service cannot represent exactly, while a fractionalDoubleremains a type error. Does not yet cover integer elements inside a uniformFloat64array or an enum variant. (#4976) - Added driver-internal resolution of containers by resource id (RID).
CosmosDriver::resolve_container_by_ridreads a container’s metadata addressing it purely by RID (deriving the parent database RID from the container RID, so noread_databaseround-trip is needed) and caches the result in a by-RID index. References are validated for consistent name/RID addressing inplan_operation— the single choke point every executable operation passes through, including multi-page queries — returning a deterministicCLIENT_MIXED_NAME_RID_ADDRESSINGerror before signing instead of letting the gateway reject a mixed name/RID request with an opaque401. The newCLIENT_INVALID_RESOURCE_IDandCLIENT_MIXED_NAME_RID_ADDRESSINGclient 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
DISTINCTquery support (ordered and unordered), composed as a stage above the fan-out root and below anyOFFSET/LIMIT/TOPwindow (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. OrderedDISTINCT— onlySELECT DISTINCT VALUE <path> … ORDER BY <same path>, the one shape the service reports as ordered; list projections and multi-columnORDER BYare unordered — is resumable, carrying only the last emitted hash in its continuation token. UnorderedDISTINCTis not:OperationPlan::to_continuation_tokenfails with the newCosmosStatus::CLIENT_DISTINCT_CONTINUATION_UNSUPPORTED(HTTP 400) rather than returning a token whose resume would re-emit rows. A partition split that reaches theDISTINCTstage is refused withCosmosStatus::CLIENT_DISTINCT_CANNOT_FORWARD_SPLIT(HTTP 500) instead of being forwarded, sinceSplitRequiredreplaces the node that emits it and would discard the deduplication state. (#5026) - Added an SDK-generated
x-ms-client-idheader that remains stable for eachCosmosDriver, 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 viaOperationOptions.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 pointDocumentitem operations. Off by default and inert on the wire when unset. (#4671) - Extended binary response negotiation to
Query/SqlQueryonDocument: a query advertises a binary response while keeping its text request body, and every pipeline — passthrough, the streaming cross-partitionORDER BYmerge, andOFFSET/LIMIT/TOP— carries binary pages through to the SDK’s integer-preserving deserializer.BinaryEncodingOptions::request_text_responseis 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(withDEFAULT_MAX_FAN_OUT) toCosmosDriver::plan_operation, enforcing a maximum fan-out on fresh cross-partition plans. A fresh plan spanning more leaf request nodes thanPlanOptions::max_fan_out(default 100) is rejected with the newCosmosStatus::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 OpenTelemetrydb.operation.name(e.g.read_item,query_items,execute_batch, andread_all_items_of_logical_partitionfor 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 oneDiagnosticsContextaggregates attempts from more than one operation — today a PATCH, whose attempts reportpatch_read_item/patch_replace_itemwhile the context reportspatch_item— and isNoneotherwise, meaning the attempt shares the context’s operation name.CosmosOperation::is_patch_sub_operationreports 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(viaDriverOptionsBuilder::with_hedging_options), bounding how many metadata operations may make simultaneous cross-region attempts. Defaults to 32;0disables 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 BYquery 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 thatwith_on_send_succeededandwith_on_send_failedregister, 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, onflush, and onclose. The defaults are a 1 second maximum wait time and 1500 buffered events for each partition, matching the .NET, JavaScript, and Python clients.flushsets a barrier over the events accepted before the call,closesends the buffered events, andabortabandons 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, andSendBatchFailedContext. (#4873) - Added the
ErrorKind::SendNotAcceptederror variant. The buffered producer reports an AMQPModifiedorReleasedoutcome as a delivery failure, because neither outcome means that the service durably stored the events.ProducerClient::send_batchkeeps its historical behavior and treats both as success with a warning. - Added connection-string authentication.
ProducerClientBuilderandConsumerClientBuildernow have anopen_with_connection_stringmethod that authenticates with a Shared Access Signature parsed from an Event Hubs connection string (Endpoint=sb://...;SharedAccessKeyName=...;SharedAccessKey=..., optionally withEntityPath, or a pre-formedSharedAccessSignature). The connection-string parser is exposed publicly asConnectionString. This reaches parity with the other Azure SDKs for development and test scenarios; Microsoft Entra ID viaopenwith aTokenCredentialremains the recommended path for production. The parser rejects empty required values and empty Event Hub names up front, and a pre-formedSharedAccessSignaturereports its ownseas 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_transportbuilder method onProducerClientandConsumerClient, which takes theAmqpTransportofazure_core_amqp(re-exported asmodels::AmqpTransport).AmqpTransport::WebSockettunnels 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. TheEventProcessorinherits the transport from theConsumerClientpassed tobuild, so it runs over WebSockets when that client selects them. (#3601) - Added the
fe2o3_amqp,fe2o3_amqp_rustls,fe2o3_amqp_ws, andfe2o3_amqp_ws_rustlsfeatures, which forward the matching features ofazure_core_amqp. Thedefaultfeature 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 ofsdk/coreuses. 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 onfe2o3-amqpandfe2o3-amqp-wswith the stack you want; Cargo unifies the features.samples/list_blobs_native_tlsshows the same pattern forreqwest. - Added the
ErrorKind::InvalidBatchSize { requested, max_allowed }error variant.create_batchreports it whenEventDataBatchOptions::max_size_in_bytesis 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 theArgumentOutOfRangeExceptionthat .NET raises and the typed error that Go returns for the same input. - Added the
ErrorKind::MissingCheckpointMetadata { partition_id }error variant.PartitionClient::update_checkpointreports 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 theInvalidOperationExceptionthat .NET raises for the same input.
Bugs Fixed
-
ProducerClient::closenow stops the authorization refresh task, so repeated producer life cycles release task-held memory. (#4595) -
ConsumerClient::closeandProducerClient::closenow close the connection when another object still holds it, most often anEventReceiverthat 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::closenow 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
$cbslink for each connection, so a client that attached more than one link at once could fail withNotAllowed. -
EventDataBatchOptions::max_size_in_bytesnow takes effect. A batch keeps the requested size, andcreate_batchreports 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::ConsumerDisconnectedwhen the broker reportsamqp:link:stolenon 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
ReconnectConnectionrecovery 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_pathand 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 thestd::io::ErrorwithErrorKind::TimedOut. The cause was boxed twice, which stored aBox<std::io::Error>and made every downcast tostd::io::ErrorreturnNone. (#5098) -
InMemoryCheckpointStorenow rotates the ETag and refresheslast_modified_timewhen an existing ownership is renewed, matching the create path and the productionBlobCheckpointStore. 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_checkpointno 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 inBlobCheckpointStore, because that store rewrites the whole blob metadata on each update. (#5097)
Breaking Changes
- The
defaultfeature now selectsfe2o3_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, namefe2o3_amqp, and take a direct dependency onfe2o3-amqpwith itsnative-tlsfeature. (#4189) -
PartitionClient::update_checkpointnow returns an error when the event carries no offset and no sequence number. Such a call returnedOk(())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
WorkloadIdentityCredentialOptionsthroughenable_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, andSpan::end_at, along with aSpanOptionsstruct, to allow reconstructing spans with explicit (backdated) start and end timestamps. These are additive with default implementations, so existingTracer/Spanimplementations continue to work unchanged. - Added
DeserializeWith::deserialize_fromwith a body-only default, allowing custom model decoders to inspect response headers without requiring serde deserialization. - Added cloneable
stream::ReadStreamandstream::SeekableReadStreamadapters, along withRequestContent::from_readerandRequestContent::from_seekable_reader, to build request bodies fromfutures::io::AsyncReadsources.
TypeSpec Core 1.2.0-beta.1 Changelog
Bugs Fixed
- Added
azure-deprecatingto 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.