UTL_HTTP调用HTTPS必报ORA-29024,因Oracle不内置公共CA信任库,仅信任Wallet中显式添加的根证书和中间证书;缺一即证书校验失败。
必须配置 oracle wallet,且 wallet 中需包含目标 https 端点的完整信任链(根证书 + 中间证书),否则 utl_http 会直接报 ora-29024: certificate validation failure —— 这不是网络不通,而是证书校验阶段就失败了。
为什么 UTL_HTTP 调用 HTTPS 一定会报 ORA-29024?
Oracle 不内置公共 CA 信任库(如 Mozilla CA Bundle),UTL_HTTP 在 SSL 握手时只信任 Wallet 里显式添加的证书。即使目标网站用的是 Let’s Encrypt 或 DigiCert,只要没导入对应根证书,就会拒绝连接。
- 错误现象:
ORA-29024: Certificate validation failure,堆栈里带UTL_HTTP.BEGIN_REQUEST - 常见误判:以为是代理、防火墙或 DNS 问题,实际 Wallet 根本没配或证书不全
- 验证方法:用
orapki wallet display -wallet查看Trusted Certificates列表是否含目标站点签发机构 - 注意:自签名证书不能只导出服务器证书,必须把整个证书链(含中间 CA)合并为 PEM 文件再导入 Wallet
如何用 orapki 创建并填充 Wallet?
Wallet 必须用 orapki 命令行工具创建,Oracle Wallet Manager(图形界面)在云环境(如 ADB)不可用,且不支持批量导入证书链。
- 创建空 Wallet:
orapki wallet create -wallet /home/oracle/wallet -pwd "MyPass123" -auto_login - 导入根证书(PEM 格式):
orapki wallet add -wallet /home/oracle/wallet -trusted_cert -cert /tmp/DigiCert_Global_Root_CA.pem - 导入中间证书(同样用
-trusted_cert):orapki wallet add -wallet /home/oracle/wallet -trusted_cert -cert /tmp/DigiCert_TLS_RSA_SHA256_2020_CA1.pem - 验证是否成功:
orapki wallet display -wallet /home/oracle/wallet,确认输出中出现对应 CN(如CN=DigiCert Global Root CA)
UTL_HTTP.SET_WALLET 的路径和权限怎么写才有效?
UTL_HTTP.SET_WALLET 的第一个参数是 Wallet 所在目录路径(不是 Wallet 文件名),第二个参数是 Wallet 密码;路径格式错误或权限不足会导致静默失败或 ORA-24247。
- 正确写法(Linux/Unix):
UTL_HTTP.SET_WALLET('file:/home/oracle/wallet', 'MyPass123'); - 错误写法:
'file:/home/oracle/wallet/ewallet.p12'(传了文件名,不是目录)、'/home/oracle/wallet'(缺file:协议头) - 权限要求:Oracle 数据库进程用户(如
oracle)必须对 Wallet 目录有读取权限,且 Wallet 文件(ewallet.p12,cwallet.sso)不能被其他用户写入(否则 Oracle 拒绝加载) - 云环境特例(ADB):Wallet 必须上传到 Object Storage,并通过
DBMS_CLOUD.CREATE_CREDENTIAL绑定,不能用本地文件路径
为什么 Wallet 配好了还报 ORA-24247?
ORA-24247 表示 Wallet 加载成功但网络 ACL 拦截了请求——这是独立于证书校验的第二道关卡,常被忽略。
- ACL 必须显式授权目标主机和端口:
DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL的host参数要填域名或 IP,lower_port/upper_port必须精确匹配(HTTPS 是 443,不能写成 440–450) - 用户必须同时拥有
connect和resolve权限:resolve用于 DNS 解析,漏掉会导致ORA-29273+ORA-12545 - 检查 ACL 是否生效:
SELECT * FROM DBA_NETWORK_ACLS WHERE HOST = 'api.example.com'; - 注意:ACL 对
localhost、127.0.0.1同样生效,内网调用也必须配置
Wallet 路径、证书链完整性、ACL 主机端口三者必须全部匹配,缺一不可;其中证书链最容易漏掉中间 CA,而 ACL 的 resolve 权限最容易被当成可选项跳过。











