发布日期: 2026-03-30
版本号: v1.16.12

Dapr 1.16.12版本包含多项错误修复,主要解决安全漏洞、Pulsar组件模式处理以及调度器集群稳定性问题。安全方面修复了gRPC授权绕过漏洞(CVE-2026-33186),该漏洞可能导致未授权的gRPC请求,用户需升级至此版本以消除风险。Pulsar发布/订阅组件修复了Avro模式订阅失败、模式注册不匹配以及JSON模式未验证等问题,这些问题曾导致Avro主题消息无法投递、模式契约失效等。调度器集群在Pod重启后可能卡顿长达20分钟的问题现已解决,通过优化触发投递路径,将恢复时间缩短至5秒以内。所有受影响版本的用户建议升级。

更新内容 (中文)

Dapr 1.16.12

此次更新包含错误修复:

安全:gRPC授权绕过

问题

Dapr使用的一个上游依赖(google.golang.org/grpc)引入了一个漏洞,在某些条件下可能允许gRPC授权绕过(CVE-2026-33186)。

影响

运行受影响版本的用户可能面临未授权gRPC请求的风险。

根本原因

问题源于一个上游库。

解决方案

此版本将受影响的依赖升级到解决CVE-2026-33186的版本。

强烈建议用户升级到此版本。

Pulsar发布/订阅JSON和Avro模式验证修复

问题

Pulsar发布/订阅组件在JSON和Avro模式处理上存在多个问题:

  1. Avro订阅路径中断: 当Pulsar主题配置了Avro模式时,消息以原始Avro二进制字节的形式传递给订阅者。Dapr运行时尝试对这些字节执行json.Unmarshal并失败,出现以下错误:

    error deserializing cloud event in pubsub <component> and topic <topic>:
    invalid character '\x06' looking for beginning of value
    

    每个在Avro强制主题上的消息都会陷入永久重试循环,永远不会传递给应用程序。

  2. Avro模式/线路格式不匹配: 启用CloudEvents封装时(默认),线路格式是CloudEvents信封,但注册到Pulsar模式注册表的Avro模式是内部领域事件模式——而非信封。这导致注册表中的模式与主题中实际存储的消息不匹配。

  3. JSON模式未验证: .jsonschema路径仅检查有效负载是否为有效JSON(json.Unmarshal),而未根据实际模式定义进行验证。不符合模式的无效有效负载被接受并发布。

影响

  • 订阅Avro强制执行的Pulsar主题的应用程序无法接收消息——它们在主题中累积,永远不会被传递。
  • 依赖代理模式注册表的模式感知Pulsar消费者(包括非Dapr消费者)收到的模式与实际CloudEvents消息格式不匹配。
  • 依赖Pulsar JSON模式执行的应用程序可能发布结构无效的消息,违反模式契约,导致下游消费者失败。

受影响版本:v1.16.0至v1.16.11。

解决方案

  1. Avro订阅解码: 当入站主题注册了Avro模式时,订阅者现在使用缓存的编解码器(NativeFromBinary)将二进制有效负载解码为原生Go类型,然后重新编码为JSON(TextualFromNative)后再传递给处理程序。没有Avro模式的主题不受影响。

  2. CloudEvents信封模式: 启用CloudEvents封装时,Dapr现在在将用户提供的Avro模式注册到代理之前,将其包装在CloudEvents信封Avro模式中,遵循CloudEvents Avro格式规范。新的主题级<topic-name>.rawSchema元数据选项可跳过专门用于原始有效负载的主题的封装。现在,使用rawPayload=true发布到CloudEvents封装的主题会被拒绝并显示明确错误。

  3. JSON模式验证: JSON模式主题现在在初始化时编译一个goavro编解码器(因为Pulsar JSON模式使用Avro模式定义),并在发布时使用NativeFromTextual验证有效负载以实现完整的结构验证。无效模式在启动时快速失败。CloudEvents信封模式生成和rawPayload防护与Avro路径行为匹配。

调度器集群在工作流运行时Pod重启后停滞长达20分钟

问题

在调度器Pod重启后(由于滚动更新、节点维护、Pod驱逐或OOM终止),整个调度器集群可能停滞数分钟。 在此期间,没有工作流执行,没有计划作业触发,也没有Actor提醒传递。

调度器Pod保持运行并通过健康检查。 日志在一个或多个实例上显示"fetched initial leadership, waiting for quorum for partition total",然后约20分钟的静默,直到出现"leadership quorum reached"并恢复正常使用。

影响

任何使用调度器在HA模式(3个实例)下运行活跃工作流或Actor提醒负载的Dapr部署都会受到影响。 当调度器Pod在作业被触发并传递到daprd sidecar的过程中重启时,会发生停滞。

根本原因

当调度器Pod重启时,剩余实例检测到领导分区更改(即3->2)并尝试重启其cron引擎。 引擎关闭序列关闭所有内部作业计数器循环,每个循环必须在关闭前完成任何进行中的触发。

触发传递路径调用Pool.Trigger,将作业入队到连接池并阻塞等待daprd sidecar以成功/失败结果响应。 ctx参数在引擎关闭期间被取消,但被接受且从未检查。 如果daprd sidecar响应缓慢、崩溃、已断开连接或正在重启(滚动更新期间常见),响应永远不会到达,Pool.Trigger无限期阻塞。

这阻止引擎关闭,从而阻止cron模块调用Reelect以使用新的分区总数更新其领导键。 其他调度器实例看到此陈旧的键,无法达成法定人数协议。集群在停滞实例的etcd租约过期前一直卡住。

解决方案

Pool.Trigger现在使用select同时监听响应通道和ctx.Done()

当引擎上下文在法定人数更改期间被取消时,所有进行中的触发立即返回UNDELIVERABLE。响应通道在后台被清空,以便来自流关闭的后期回调不会损坏后续触发调用。引擎在毫秒内关闭,Reelect更新领导键,集群在新的分区总数上收敛。未传递的作业在下一个引擎周期自动重试。

此外,新daprd连接期间失败的DeliverablePrefixes调用不再终止整个连接池。失败的连接被单独取消,允许daprd重新连接而不干扰其他健康连接。

这将调度器Pod重启后的集群恢复时间从长达20分钟减少到5秒以内。

注意: 此问题不影响Dapr v1.17或更高版本。v1.17版本将触发传递路径从同步阻塞模式(v1.16的Pool.Trigger等待响应通道)重新设计为异步回调模式,其中触发函数立即返回,响应通过回调到达。没有阻塞调用,法定人数更改期间没有东西可以阻止引擎关闭。

更新内容 (原始)

Dapr 1.16.12

This update includes bug fixes:

Security: gRPC authorization bypass

Problem

An upstream dependency (google.golang.org/grpc) used by Dapr introduced a vulnerability that could allow gRPC authorization bypass under certain conditions (CVE-2026-33186).

Impact

Users running affected versions could be exposed to unauthorized gRPC requests.

Root Cause

The issue originated in an upstream library.

Solution

This release upgrades the affected dependency to a version that resolves CVE-2026-33186.

Users are strongly encouraged to upgrade to this release.

Pulsar pub/sub JSON and Avro schema validation fixes

Problem

The Pulsar pub/sub component had several issues with JSON and Avro schema handling:

  1. Avro subscribe path broken: When a Pulsar topic has an Avro schema configured, messages are delivered to the subscriber as raw Avro binary bytes. The Dapr runtime attempts json.Unmarshal on those bytes and fails with:

    error deserializing cloud event in pubsub <component> and topic <topic>:
    invalid character '\x06' looking for beginning of value
    

    Every message on an Avro-enforced topic gets stuck in a permanent retry loop and is never delivered to the application.

  2. Avro schema/wire format mismatch: When CloudEvents wrapping is enabled (the default), the wire format is a CloudEvents envelope, but the Avro schema registered with the Pulsar Schema Registry was the inner domain event schema — not the envelope. This causes a mismatch between the schema in the registry and the actual messages stored in the topic.

  3. JSON schema not validated: The .jsonschema path only checked that the payload was valid JSON (json.Unmarshal) without validating it against the actual schema definition. Invalid payloads that do not conform to the schema were accepted and published.

Impact

  • Applications subscribing to Avro-enforced Pulsar topics cannot receive messages — they accumulate in the topic and are never delivered.
  • Schema-aware Pulsar consumers (including non-Dapr consumers) that rely on the broker’s schema registry receive a schema that does not match the actual CloudEvents message format.
  • Applications relying on Pulsar’s JSON schema enforcement could publish structurally invalid messages that violate the schema contract, leading to downstream consumer failures.

Affected versions: v1.16.0 through v1.16.11.

Solution

  1. Avro subscribe decode: When an Avro schema is registered for the incoming topic, the subscriber now decodes the binary payload to native Go types using the cached codec (NativeFromBinary), then re-encodes as JSON (TextualFromNative) before passing to the handler. Topics without an Avro schema are unaffected.

  2. CloudEvents envelope schema: When CloudEvents wrapping is enabled, Dapr now wraps the user-provided Avro schema inside a CloudEvents envelope Avro schema before registering it with the broker, following the CloudEvents Avro format spec. A new topic-level <topic-name>.rawSchema metadata option skips envelope wrapping for topics dedicated to raw payloads. Publishing with rawPayload=true to a CloudEvents-wrapped topic is now rejected with a clear error.

  3. JSON schema validation: JSON schema topics now compile a goavro codec at init time (since Pulsar JSON schemas use Avro schema definitions) and validate payloads using NativeFromTextual at publish time for full structural validation. Invalid schemas fail fast at startup. CloudEvents envelope schema generation and rawPayload guards match the Avro path behavior.

Scheduler cluster stalls for up to 20 minutes after pod restart when workflows are running

Problem

After a Scheduler pod restart (due to a rolling update, node maintenance, pod eviction, or OOM kill), the entire Scheduler cluster can stall for minutes. During this time, no workflows execute, no scheduled jobs fire, and no actor reminders are delivered.

The Scheduler pods remain running and pass health checks. Logs show "fetched initial leadership, waiting for quorum for partition total" on one or more instances, followed by approximately 20 minutes of silence before "leadership quorum reached" appears and normal operation resumes.

Impact

Any Dapr deployment using Scheduler in HA mode (3 instances) with active workflow or actor reminder workloads is affected. The stall occurs when a Scheduler pod restarts while jobs are actively being triggered and delivered to daprd sidecars.

Root Cause

When a Scheduler pod restarts, the remaining instances detect a leadership partition change (i.e., 3->2) and attempt to restart their cron engines. The engine shutdown sequence closes all internal job counter loops, each of which must complete any in-flight trigger before shutting down.

The trigger delivery path calls Pool.Trigger, which enqueues the job to the connection pool and blocks waiting for the daprd sidecar to respond with a success/failure result. The ctx parameter which is cancelled during engine shutdown is accepted but never checked. If a daprd sidecar is slow to respond, crashed, has disconnected, or is itself restarting (common during a rolling update), the response never arrives and Pool.Trigger blocks indefinitely.

This prevents the engine from shutting down, which prevents the cron module from calling Reelect to update its leadership key with the new partition total. The other Scheduler instances see this stale key and cannot reach quorum agreement. The cluster is stuck until the stalled instance’s etcd lease expires.

Solution

Pool.Trigger now uses a select on both the response channel and ctx.Done().

When the engine context is cancelled during a quorum change, all in-flight triggers return UNDELIVERABLE immediately. The response channel is drained in the background so that late callbacks from stream shutdown do not corrupt subsequent trigger calls. The engine shuts down within milliseconds, Reelect updates the leadership key, and the cluster converges on the new partition total. The undelivered jobs are automatically retried on the next engine cycle.

Additionally, a failed DeliverablePrefixes call during a new daprd connection no longer kills the entire connection pool. The failed connection is cancelled individually, allowing the daprd to reconnect without disrupting other healthy connections.

This reduces cluster recovery time after a Scheduler pod restart from up to 20 minutes to under 5 seconds.

Note: This issue does not affect Dapr v1.17 or later. The v1.17 release redesigned the trigger delivery path from a synchronous blocking pattern (v1.16’s Pool.Trigger waiting on a response channel) to an asynchronous callback pattern where the trigger function returns immediately and the response arrives via a callback. With no blocking call, there is nothing to stall the engine shutdown during quorum changes.

下载链接