TL;DR: DBMS_CLOUD requires valid HTTPS certificates with matching hostnames. Self-signed certs or HTTP-only? DBMS_CLOUD won’t work. This post shows what breaks and why.
Version Note: This uses Oracle 26ai (23.26.1.0.0). SSL handling behavior changed in 23ai. On 19c/21c,
sqlnet.orasettings likeSSL_SERVER_DN_MATCH=NOstill work, so self-signed certs may be viable with additional configuration. The steps here are 26ai-specific.Prior Art: Ron Ekins documented DBMS_CLOUD with FlashBlade for 19c in this 2022 post. His approach works if you control the certificate CN and can match it to your endpoint URL. This post covers what happens when you can’t: default vendor certificates with generic CNs, IP-based access, and the SSL behavior changes in 26ai that break workarounds that worked in 19c.
Oracle 26ai can connect to S3-compatible object storage for external table access. We’re setting up credentials, network ACLs, SSL wallets, and connectivity testing against a Pure Storage FlashBlade, documenting the real errors you’ll hit with self-signed certificates and HTTP-only endpoints.
Oracle provides two paths for S3 access: DBMS_CLOUD (the managed approach, requires HTTPS with valid certificates) and ORACLE_BIGDATA (the external table driver, more flexible but lower-level). We tested DBMS_CLOUD against a FlashBlade endpoint. If your object storage uses self-signed certs or HTTP-only, you’ll hit the blockers documented here.
Why You’d Do This
Data Warehouse Modernization
The traditional Oracle data warehouse model assumes everything lives in the database. ETL pipelines load data, transformations happen in PL/SQL or SQL, consumers query Oracle directly. This worked when Oracle was the only game in town.
That’s not the world anymore. Data engineering teams use Spark, Trino, DuckDB, and Python. They write Parquet and Iceberg to object storage. Data scientists train models against those same files. BI tools query both Oracle and the lake. The warehouse is no longer a monolith; it’s one node in a larger ecosystem.
S3-compatible object storage becomes the common layer. Oracle external tables let the database participate without forcing everything through ETL. DBAs query the same Parquet files that data engineers produce. No duplication, no sync jobs, no drift.
Multi-Engine Analytics
Different workloads need different engines. Oracle excels at transactional consistency, complex joins across normalized schemas, and workloads where the optimizer’s cost-based decisions matter. Spark excels at distributed transformations over denormalized data. Trino excels at federated queries across heterogeneous sources.
With data on object storage in open formats, you pick the right engine for each job. Oracle queries the customer dimension table it owns. Spark processes the clickstream Parquet. Trino joins them together. The storage layer is shared; the compute is specialized.
Prerequisites
- Oracle 26ai (23.26.1.0.0), on-prem, CDB/PDB architecture
- S3-compatible object storage with known endpoint, access key, and secret key
SYSDBAaccess to the CDB rootSYSTEMaccess to the target PDB- Root/OS access to the database server (for wallet management)
- AWS CLI installed on the Oracle server (for S3 connectivity testing)
Lab environment:
| Component | Value |
|---|---|
| Oracle | 26ai Enterprise Edition 23.26.1.0.0 on Oracle Linux 9.7 |
| CDB / PDB | ORCL / ORCLPDB |
| ORACLE_HOME | /u01/app/oracle/product/26ai/dbhome_1 |
| Object Storage | Pure Storage FlashBlade at 10.21.227.93 (HTTP:80, HTTPS:443 with self-signed cert) |
| Test Data | Synthetic Customer360 dataset (~552 GB of Parquet) |
Step-by-Step
Step 1: Install DBMS_CLOUD
In Oracle 26ai, DBMS_CLOUD is pre-installed. If you need to install or reinstall it, run dbms_cloud_install.sql from the CDB root as SYSDBA:
-- Connected as SYSDBA to CDB root
@$ORACLE_HOME/rdbms/admin/dbms_cloud_install.sql
This is a wrapper that calls catdbmscloud.sql, catdbmscloudpls.sql, and prvtdbmscloudpls.sql. There’s also catclouduser.sql for creating the cloud user separately. In 26ai, both the package and user should already exist. Verify in your target PDB:
ALTER SESSION SET CONTAINER = ORCLPDB;
SELECT owner, object_name, object_type, status
FROM dba_objects
WHERE object_name = 'DBMS_CLOUD' AND object_type IN ('PACKAGE','PACKAGE BODY');
OWNER OBJECT_NAME OBJECT_TYPE STATUS
------ ------------ ------------- ------
SYS DBMS_CLOUD PACKAGE VALID
SYS DBMS_CLOUD PACKAGE BODY VALID
Reference: Installing DBMS_CLOUD
Step 2: Create S3 Credentials
Create credentials in the PDB where you’ll query data.
For DBMS_CLOUD:
BEGIN
DBMS_CLOUD.CREATE_CREDENTIAL(
credential_name => 'FLASHBLADE_CRED',
username => 'PSFBSAZRAHPIIILFENLAMIFKOFCNMFMCKJOIDBGIIE', -- S3 Access Key
password => '8D64138E9a2c5cd25/e77f+9DA87BC4ceeaf4c4OHNK' -- S3 Secret Key
);
END;
/
For ORACLE_BIGDATA:
BEGIN
DBMS_CREDENTIAL.CREATE_CREDENTIAL(
credential_name => 'S3_FLASHBLADE',
username => 'PSFBSAZRAHPIIILFENLAMIFKOFCNMFMCKJOIDBGIIE',
password => '8D64138E9a2c5cd25/e77f+9DA87BC4ceeaf4c4OHNK'
);
END;
/
Reference: DBMS_CLOUD CREATE_CREDENTIAL
Step 3: Configure Network ACLs
Oracle blocks outbound HTTP by default.
In the PDB:
ALTER SESSION SET CONTAINER = ORCLPDB;
BEGIN
DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
host => '10.21.227.93',
lower_port => 80,
upper_port => 443,
ace => xs$ace_type(
privilege_list => xs$name_list('http','http_proxy'),
principal_name => 'SYSTEM',
principal_type => xs_acl.ptype_db
)
);
END;
/
Critical: Also add ACLs at the CDB root. Oracle’s KUPC module checks ACLs at both CDB root and PDB level. PDB-only ACLs fail with ORA-17361.
-- Connected as SYSDBA at CDB root (NOT in PDB context)
BEGIN
DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
host => '10.21.227.93',
lower_port => 80,
upper_port => 443,
ace => xs$ace_type(
privilege_list => xs$name_list('http','http_proxy'),
principal_name => 'SYSTEM',
principal_type => xs_acl.ptype_db
)
);
END;
/
Step 4: Test HTTP Connectivity
SET SERVEROUTPUT ON
DECLARE
req UTL_HTTP.REQ;
resp UTL_HTTP.RESP;
BEGIN
req := UTL_HTTP.BEGIN_REQUEST('http://10.21.227.93:80');
resp := UTL_HTTP.GET_RESPONSE(req);
DBMS_OUTPUT.PUT_LINE('Status: ' || resp.status_code);
UTL_HTTP.END_RESPONSE(resp);
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error: ' || SQLERRM);
END;
/
Status: 403
A 403 is correct. The request is unsigned, so the endpoint rejects it. The point is Oracle reached it. If you get ORA-24247, your ACLs are missing.
Step 5: Set Up an SSL Wallet
mkdir -p /u01/app/oracle/admin/ORCLCDB/wallet
orapki wallet create -wallet /u01/app/oracle/admin/ORCLCDB/wallet \
-pwd WalletPassw0rd123 -auto_login
openssl s_client -connect 10.21.227.93:443 </dev/null 2>/dev/null \
| openssl x509 > /tmp/fb.pem
orapki wallet add -wallet /u01/app/oracle/admin/ORCLCDB/wallet \
-trusted_cert -cert /tmp/fb.pem -pwd WalletPassw0rd123
-- Run as SYSDBA at CDB root
ALTER DATABASE PROPERTY SET SSL_WALLET='/u01/app/oracle/admin/ORCLCDB/wallet';
Step 6: Test DBMS_CLOUD (Document the Failures)
DBMS_CLOUD requires HTTPS with valid certificates.
HTTP URL:
BEGIN
DBMS_CLOUD.CREATE_EXTERNAL_TABLE(
table_name => 'TEST_HTTP',
credential_name => 'FLASHBLADE_CRED',
file_uri_list => 'http://10.21.227.93:80/lb-bronze/customer/interactions/part-000000.parquet',
format => '{"type": "parquet", "schema": "first"}'
);
END;
/
ORA-20000: ORA-20011: Invalid object uri
DBMS_CLOUD rejects HTTP. Period.
HTTPS with self-signed cert:
ORA-24263: Certificate of the remote server does not match the target address.
Our FlashBlade cert has CN=Pure Storage. It doesn’t match the IP 10.21.227.93. Oracle enforces hostname verification with no override in 26ai.
Summary:
| URL Format | Error |
|---|---|
| `http://…` | ORA-20011: Invalid object uri |
| `https://IP/…` | ORA-24263: cert hostname mismatch |
Reference: ORA-24263 on AskTom
Step 7: Verify OS-Level S3 Access
export AWS_ACCESS_KEY_ID=PSFBSAZRAHPIIILFENLAMIFKOFCNMFMCKJOIDBGIIE
export AWS_SECRET_ACCESS_KEY='8D64138E9a2c5cd25/e77f+9DA87BC4ceeaf4c4OHNK'
aws --endpoint-url http://10.21.227.93 s3 ls
2026-02-23 12:15:00 lb-bronze
2026-02-23 12:15:00 lb-silver
2026-02-23 12:15:00 lb-gold
Endpoint, credentials, network: all fine. The issue is Oracle’s TLS requirements.
Gotchas
ACLs Must Exist at Both CDB Root AND PDB Level
PDB-only ACLs fail with ORA-17361. Oracle’s KUPC module checks both levels.
SSL Behavior Changed in 23ai/26ai
In 19c/21c, SSL_SERVER_DN_MATCH=NO in sqlnet.ora bypassed hostname verification. In 26ai, this no longer works. The KUPC module enforces TLS hostname verification with no override.
Reference: SSL_SERVER_DN_MATCH parameter
DBMS_CLOUD Always Requires HTTPS
There is no way to make DBMS_CLOUD work over HTTP. If your object storage only speaks HTTP, DBMS_CLOUD is not an option. Use ORACLE_BIGDATA with local file staging instead.
Summary
DBMS_CLOUD works with AWS S3 or any endpoint with valid HTTPS certificates, but fails against on-prem S3-compatible storage with self-signed certs due to hostname verification that can’t be disabled in 26ai.
The workaround: download files to the Oracle server locally (using aws s3 cp) and read them with the ORACLE_BIGDATA driver.
