You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Rust的async_nats连接NATS时遇MissingOrMalformedExtensions错误

解决async_nats连接NATS服务器时的证书读取错误

问题场景

使用Rust的async_nats crate连接本地NATS服务器,代码如下:

use futures::StreamExt;

#[tokio::main]
async fn main() -> Result<(), async_nats::Error> {
    let client = async_nats::connect("nats://127.0.0.1:4222").await?;
    // let client = async_nats::connect("127.0.0.1:4222").await?;
    // let client = async_nats::connect("127.0.0.1").await?;
    let mut subscriber = client.subscribe("messages".into()).await?.take(10);

    for _ in 0..10 {
        client.publish("messages".into(), "data".into()).await?;
    }

    while let Some(message) = subscriber.next().await {
        println!("Received message {:?}", message);
    }

    Ok(())
}

运行时触发panic,错误信息:

Error: Custom { kind: Other, error: "failed to read root certificates: MissingOrMalformedExtensions" }
error: process didn't exit successfully: `target\debug\program.exe` (exit code: 1)

解决方案

这个错误的核心原因是客户端尝试读取系统根证书以建立TLS连接,但读取失败,或者本地NATS服务器未配置TLS但客户端自动启用了TLS验证。

1. 显式禁用TLS连接(推荐本地开发使用)

使用ClientOptions创建客户端,明确不启用TLS,避免自动触发证书验证逻辑:

use futures::StreamExt;
use async_nats::ClientOptions;

#[tokio::main]
async fn main() -> Result<(), async_nats::Error> {
    // 显式配置无TLS的客户端
    let client = ClientOptions::new()
        .connect("127.0.0.1:4222")
        .await?;
    
    let mut subscriber = client.subscribe("messages".into()).await?.take(10);

    for _ in 0..10 {
        client.publish("messages".into(), "data".into()).await?;
    }

    while let Some(message) = subscriber.next().await {
        println!("Received message {:?}", message);
    }

    Ok(())
}

2. 手动指定CA证书(若服务器启用了TLS)

如果你的NATS服务器确实配置了TLS,需要手动指定CA证书路径来修复证书读取问题:

use futures::StreamExt;
use async_nats::ClientOptions;
use rustls_pemfile::certs;
use std::fs::File;
use std::io::BufReader;

#[tokio::main]
async fn main() -> Result<(), async_nats::Error> {
    // 读取自定义CA证书文件
    let cert_file = File::open("path/to/your/ca.crt")?;
    let mut reader = BufReader::new(cert_file);
    let certs = certs(&mut reader)?
        .into_iter()
        .map(|cert| rustls::Certificate(cert))
        .collect();

    // 构建自定义TLS配置
    let tls_config = rustls::ClientConfig::builder()
        .with_safe_defaults()
        .with_root_certificates(certs)
        .with_no_client_auth();

    let client = ClientOptions::new()
        .tls(tls_config.into())
        .connect("tls://127.0.0.1:4222")
        .await?;
    
    let mut subscriber = client.subscribe("messages".into()).await?.take(10);

    for _ in 0..10 {
        client.publish("messages".into(), "data".into()).await?;
    }

    while let Some(message) = subscriber.next().await {
        println!("Received message {:?}", message);
    }

    Ok(())
}

内容的提问来源于stack exchange,提问作者Yoskutik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 09:27:22