使用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
排查方向
私钥文件与密码问题
- 生成私钥时用了
aes256加密,PRIVATE_KEY_FILE_PWD参数必须填写生成时设置的密码,不能留空,这是最可能的问题 - 检查私钥文件路径是否正确,Windows下路径用
/或转义\\,确保文件存在且内容完整(打开文件看是否有-----BEGIN ENCRYPTED PRIVATE KEY-----和对应的结尾标识) - 重新生成私钥,确认生成过程中密码输入正确,文件没有损坏
- 生成私钥时用了
JDBC URL参数问题
- Snowflake JDBC的私钥密码参数名是
private_key_file_pwd(全小写),你写成了大写PRIVATE_KEY_FILE_PWD,可能导致驱动无法识别,无法解密私钥 authenticator参数必须设置为SNOWFLAKE_JWT才能使用密钥认证,当前留空会导致驱动使用默认的用户名密码认证,和传入私钥的操作冲突- 补充完整
db、warehouse、role这些必填参数,脱敏后的空值会导致连接配置不完整
- Snowflake JDBC的私钥密码参数名是
依赖与JVM版本兼容问题
- Snowflake JDBC 3.13.26版本较老,对Java 17的支持有限,建议升级到4.x以上的版本(比如4.0.0+)
- Flyway 8.0.5和旧版Snowflake JDBC可能存在兼容性问题,尝试升级Flyway到9.x或10.x版本
文件读取权限问题
- 确保运行程序的用户有读取私钥文件的权限,Windows下可能存在文件权限限制导致驱动无法读取文件内容
内容的提问来源于stack exchange,提问作者RBA
相关产品推荐
相关产品推荐

