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

使用Flyway连接Snowflake时出现PemReader.readPemObject()返回null错误

Flyway连接Snowflake时私钥无效报错排查

生成私钥的命令

我用以下命令生成了RSA私钥:

openssl genrsa 2048 | openssl pkcs8 -topk8 -v2 aes256 -inform PEM -out rsa_key.p8

Java代码实现

通过Spring Boot + Flyway连接Snowflake执行info命令的代码(敏感信息已脱敏):

package com.example.snowflake_key;

import lombok.extern.slf4j.Slf4j;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.MigrationInfo;
import org.flywaydb.core.api.MigrationInfoService;
import org.flywaydb.core.api.MigrationVersion;
import org.flywaydb.core.api.configuration.FluentConfiguration;
import org.flywaydb.core.internal.info.MigrationInfoDumper;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import java.util.Properties;

@SpringBootApplication
@Slf4j
public class SnowflakeKeyApplication implements CommandLineRunner {

    Flyway flyway;

    public static void main(String[] args) {
        SpringApplication.run(SnowflakeKeyApplication.class, args);
    }

    @Override
    public void run(String... args) {            
        FluentConfiguration flywayConfig = Flyway.configure();

        Properties props = new Properties();
        props.put("flyway.baselineOnMigrate", "true");
        props.put("flyway.outOfOrder", "true");
        props.put("flyway.table", "FLYWAY_SCHEMA_HISTORY");
        props.put("flyway.locations", "/db/scripts");
        props.put("driver", "net.snowflake.client.jdbc.SnowflakeDriver");
        flywayConfig.configuration(props);

        flywayConfig.dataSource("jdbc:snowflake://<account>.snowflakecomputing.com/"
                        + "?db="
                        + "&warehouse="
                        + "&role="
                        + "&authenticator="
                        + "&private_key_file=D:/Projects/Java/snowflake_key/src/main/resources/rsa_key.p8"
                        + "&PRIVATE_KEY_FILE_PWD="
                , "some_user"
                , "some_password"
        );
        flywayConfig.schemas("some schema");
        flyway = flywayConfig.load();

        runInfo();
    }
         
    public void runInfo() {
        MigrationInfoService info = flyway.info();
        MigrationInfo current = info.current();
        MigrationVersion currentSchemaVersion = current == null ? MigrationVersion.EMPTY : current.getVersion();

        MigrationVersion schemaVersionToOutput = currentSchemaVersion == null ? MigrationVersion.EMPTY : currentSchemaVersion;
        StringBuffer buffer = new StringBuffer();
        buffer.append("Schema version: ")
                .append(schemaVersionToOutput).append("\n")
                .append(MigrationInfoDumper.dumpToAsciiTable(info.all()));

        log.info(buffer.toString());
    }
}

Maven依赖配置

</dependency>
    <dependency>
        <groupId>net.snowflake</groupId>
        <artifactId>snowflake-jdbc</artifactId>
        <version>3.13.26</version>
    </dependency>
    <dependency>
        <groupId>org.flywaydb</groupId>
        <artifactId>flyway-core</artifactId>
        <version>8.0.5</version>
    </dependency>

错误信息

使用Liberica 17 JVM运行时,遇到如下错误:

Private key provided is invalid or not supported:
D:/Projects/Java/snowflake_key/src/main/resources/rsa_key.p8: Cannot
invoke
"net.snowflake.client.jdbc.internal.org.bouncycastle.util.io.pem.PemObject.getContent()"
because the return value of
"net.snowflake.client.jdbc.internal.org.bouncycastle.util.io.pem.PemReader.readPemObject()"
is null

堆栈跟踪:

Caused by: org.flywaydb.core.internal.exception.FlywaySqlException: Unable to obtain connection from database (jdbc:snowflake://.....snowflakecomputing.com/?db=....&warehouse=....&role=....&authenticator=.....&private_key_file=D:/Projects/Java/snowflake_key/src/main/resources/rsa_key.p8&PRIVATE_KEY_FILE_PWD=....) for user '....': Private key provided is invalid or not supported: D:/Projects/Java/snowflake_key/src/main/resources/rsa_key.p8: Cannot invoke "net.snowflake.client.jdbc.internal.org.bouncycastle.util.io.pem.PemObject.getContent()" because the return value of "net.snowflake.client.jdbc.internal.org.bouncycastle.util.io.pem.PemReader.readPemObject()" is null
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL State  : 42601
Error Code : 200045
Message    : Private key provided is invalid or not supported: D:/Projects/Java/snowflake_key/src/main/resources/rsa_key.p8: Cannot invoke "net.snowflake.client.jdbc.internal.org.bouncycastle.util.io.pem.PemObject.getContent()" because the return value of "net.snowflake.client.jdbc.internal.org.bouncycastle.util.io.pem.PemReader.readPemObject()" is null

    at org.flywaydb.core.internal.jdbc.JdbcUtils.openConnection(JdbcUtils.java:67) ~[flyway-core-8.0.5.jar:na]
    at org.flywaydb.core.internal.jdbc.JdbcConnectionFactory.<init>(JdbcConnectionFactory.java:74) ~[flyway-core-8.0.5.jar:na]
    at org.flywaydb.core.FlywayExecutor.execute(FlywayExecutor.java:143) ~[flyway-core-8.0.5.jar:na]
    at org.flywaydb.core.Flyway.info(Flyway.java:191) ~[flyway-core-8.0.5.jar:na]
    at com.hackathon.FlywayService.runInfo(FlywayService.java:72) ~[classes/:na]
    at com.hackathon.SnowFlakeMigrationService.lambda$processSnowFlakeMigrations$0(SnowFlakeMigrationService.java:22) ~[classes/:na]
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na]
    at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: net.snowflake.client.jdbc.SnowflakeSQLLoggedException: Private key provided is invalid or not supported: D:/Projects/Java/ia-ds-snfl-load/service/src/main/resources/snowflake.p8: Cannot invoke "net.snowflake.client.jdbc.internal.org.bouncycastle.util.io.pem.PemObject.getContent()" because the return value of "net.snowflake.client.jdbc.internal.org.bouncycastle.util.io.pem.PemReader.readPemObject()" is null
    at net.snowflake.client.jdbc.DefaultSFConnectionHandler.initialize(DefaultSFConnectionHandler.java:109) ~[snowflake-jdbc-3.13.25.jar:3.13.25]
    at net.snowflake.client.jdbc.DefaultSFConnectionHandler.initializeConnection(DefaultSFConnectionHandler.java:79) ~[snowflake-jdbc-3.13.25.jar:3.13.25]
    at net.snowflake.client.jdbc.SnowflakeConnectionV1.initConnectionWithImpl(SnowflakeConnectionV1.java:116) ~[snowflake-jdbc-3.13.25.jar:3.13.25]
    at net.snowflake.client.jdbc.SnowflakeConnectionV1.<init>(SnowflakeConnectionV1.java:96) ~[snowflake-jdbc-3.13.25.jar:3.13.25]
    at net.snowflake.client.jdbc.SnowflakeDriver.connect(SnowflakeDriver.java:176) ~[snowflake-jdbc-3.13.25.jar:3.13.25]
    at org.flywaydb.core.internal.jdbc.DriverDataSource.getConnectionFromDriver(DriverDataSource.java:259) ~[flyway-core-8.0.5.jar:na]
    at org.flywaydb.core.internal.jdbc.DriverDataSource.getConnection(DriverDataSource.java:223) ~[flyway-core-8.0.5.jar:na]
    at org.flywaydb.core.internal.jdbc.JdbcUtils.openConnection(JdbcUtils.java:52) ~[flyway-core-8.0.5.jar:na]
    ... 9 common frames omitted

排查方向

  1. 私钥文件与密码问题

    • 生成私钥时用了aes256加密,PRIVATE_KEY_FILE_PWD参数必须填写生成时设置的密码,不能留空,这是最可能的问题
    • 检查私钥文件路径是否正确,Windows下路径用/或转义\\,确保文件存在且内容完整(打开文件看是否有-----BEGIN ENCRYPTED PRIVATE KEY-----和对应的结尾标识)
    • 重新生成私钥,确认生成过程中密码输入正确,文件没有损坏
  2. JDBC URL参数问题

    • Snowflake JDBC的私钥密码参数名是private_key_file_pwd(全小写),你写成了大写PRIVATE_KEY_FILE_PWD,可能导致驱动无法识别,无法解密私钥
    • authenticator参数必须设置为SNOWFLAKE_JWT才能使用密钥认证,当前留空会导致驱动使用默认的用户名密码认证,和传入私钥的操作冲突
    • 补充完整db、warehouse、role这些必填参数,脱敏后的空值会导致连接配置不完整
  3. 依赖与JVM版本兼容问题

    • Snowflake JDBC 3.13.26版本较老,对Java 17的支持有限,建议升级到4.x以上的版本(比如4.0.0+)
    • Flyway 8.0.5和旧版Snowflake JDBC可能存在兼容性问题,尝试升级Flyway到9.x或10.x版本
  4. 文件读取权限问题

    • 确保运行程序的用户有读取私钥文件的权限,Windows下可能存在文件权限限制导致驱动无法读取文件内容

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 20:07:04