Integrate customer-hosted Python artifact repositories

Customer-hosted artifact repositories connect private Python artifact repository solutions directly to Snowflake. By integrating these external repositories, you can use the same package management workflows you already apply internally.

Note

Warehouse-based Snowflake Notebooks, Streamlit, Snowflake Native Apps, and SPCS services are currently not supported.

Customer-hosted artifact repositories let you reuse the same package management and governance systems you already rely on, while making them available to Snowflake Python workloads. You can configure these repositories using API integrations and secrets, even setting them as account-wide defaults to simplify deployment.

Customer-hosted artifact repositories support PrivateLink for enhanced networking. This effectively bridges the gap between internal security standards and cloud-based data science workflows.

Key ways this integration improves security and governance include:

  • Flexibility: Snowflake Package Policy has been expanded to support all Artifact Repositories, including customer-hosted repository objects.
  • Security and Compliance: Use existing package governance and policies in customer-hosted repositories.
  • Consistency: Customers can manage Snowflake packages using the same repositories they manage other code bases.

Authentication methods

During the Private Preview, the supported authentication methods for customer-hosted artifact repositories are:

  • Username and password
  • Tokens

These credentials must be stored securely within a Snowflake SECRET object. OAuth and IAM-based authentication are not supported during the Private Preview.

Configure a customer-hosted artifact repository

To configure a customer-hosted artifact repository in Snowflake, you must create and link three primary Snowflake objects:

  • Snowflake SECRET: This object is used to securely store the repository credentials, such as a username and password or a token.
  • API integration: This object describes the network path to reach the repository, specifying whether the connection should go through the public Internet or via a PrivateLink endpoint for enhanced security.
  • Artifact repository object: This is the core object that ties together the API integration, the index URL of the repository, and the associated secret.

The following steps outline how to set this up:

  1. Create a Secret for credentials

    First, you must create a Snowflake SECRET to securely store the credentials (username/password or token) required to access your repository.

    -- Create a secret for credentials
    CREATE OR REPLACE SECRET my_repo_secret
      TYPE = PASSWORD
      USERNAME = 'your_username'
      PASSWORD = 'your_password_or_token';
    
  2. Create an API integration

    Create an API integration to describe the route to the repository. You have two options:

    • Public HTTPS: For repositories accessible over the Internet.

      CREATE OR REPLACE API INTEGRATION python_repo_integration
        API_PROVIDER = ARTIFACT_REPOSITORY_API
        API_ALLOWED_PREFIXES = ('https://nexus.example.com', 'https://artifactory.example.com')
        ALLOWED_AUTHENTICATION_SECRETS = (my_repo_secret)
        ENABLED = TRUE;
      

      Egress IP: You can securely allow ingress access from Snowflake to your package repository by allowing egress IP address ranges generated from Snowflake through the repository’s network firewall. To generate and use Snowflake egress IP addresses, follow these steps:

      Note

      Egress IP is available only for external access on AWS.

      1. Call SYSTEM$GET_SNOWFLAKE_EGRESS_IP_RANGES to get the current and upcoming IP ranges and their expiration times.
      2. Use the IP ranges you obtain to update firewall rules by using APIs, CLIs, or configuration management tools, as described in Automate IP address range refreshes.
    • PrivateLink: For internal repositories, use the parameter USE_PRIVATELINK_ENDPOINT = TRUE to ensure traffic stays within a VPC/VNet.

      Note

      Private Link requires Business Critical Edition (or higher).

      • Provision a private connectivity endpoint in the Snowflake VPC or VNet to enable Snowflake to connect to your repository service. For information about how to do this, see SYSTEM$PROVISION_PRIVATELINK_ENDPOINT.
      • Use the following code to create an API integration that uses private connectivity:
      CREATE OR REPLACE API INTEGRATION python_repo_integration_pl
        API_PROVIDER = ARTIFACT_REPOSITORY_API
        API_ALLOWED_PREFIXES = ('https://nexus-pl.internal.example.com')
        USE_PRIVATELINK_ENDPOINT = TRUE
        ALLOWED_AUTHENTICATION_SECRETS = (my_repo_secret)
        ENABLED = TRUE;
      
  3. Create the Artifact Repository object

    This object ties the previous components together with your repository’s index URL.

    -- Create the artifact repository object
    CREATE OR REPLACE ARTIFACT REPOSITORY my_python_repo
      TYPE = PYPI
      API_INTEGRATION = python_repo_integration
      INDEX_URL = 'https://nexus.example.com/repository/pypi-proxy/simple/'
      AUTHENTICATION_SECRET = my_repo_secret
      COMMENT = 'Customer-hosted Python package repository (Nexus)';
    

Following is an example of a Python UDF:

CREATE OR REPLACE FUNCTION test_udf()
  RETURNS STRING
  LANGUAGE PYTHON
  RUNTIME_VERSION = 3.10
  ARTIFACT_REPOSITORY = my_python_repo
  PACKAGES = ('test_whl_package')
  HANDLER = 'test'
AS $$
import test_whl_package

def test():
  return test_whl_package.say_hello()
$$;

SELECT test_udf();

You can use customer-hosted repositories in Python stored procedures too. Note that your repository needs to host Snowpark for stored procedures to work.

CREATE OR REPLACE PROCEDURE test_sproc()
RETURNS STRING
LANGUAGE PYTHON
RUNTIME_VERSION = '3.11'
ARTIFACT_REPOSITORY = my_python_repo
PACKAGES = ('snowflake-snowpark-python', 'test_whl_package')
HANDLER = 'run'
AS $$
def run(session):
  return test_whl_package.say_hello()
$$;

CALL test_sproc();

For Business Critical and VPS (Virtual Private Snowflake) customers, Snowflake supports the outbound private connectivity feature, which lets you set up a private connection between your Snowflake account and your cloud infrastructure.

To use this functionality, you must ensure proper setup of all infrastructure components on both sides: the Snowflake console and your own infrastructure.

Note

Snowflake supports only connections within the same cloud provider. For example, both Snowflake and your components must be in AWS.

On the customer infrastructure side, a Private Link Service needs to be created so the Private Endpoint provisioned in Step 2 can reach out. If the target Private Link Service is a VPC endpoint service, it needs to accept Snowflake’s principal ARN, which can be obtained from the SYSTEM$GET_PRIVATELINK_CONFIG system function.

With the Private Link Service, you should add necessary infrastructure components on your side to redirect the traffic to your repository server. The setup depends on where the repository server is located.

Repository server outside of the VPC

If the repository server is located outside of the cloud provider, then the traffic that goes from Snowflake to the Private Link Service needs to be redirected to this server. The recommended component for this is an nginx proxy. The proxy redirects all HTTPS (port 443) traffic to the repository server.

Architecture diagram showing Snowflake connecting through Private Link to an nginx proxy, which redirects traffic to a JFrog server outside the VPC.

Note

This diagram uses JFrog as an example. You can replace JFrog with any PyPI-compatible repository.

Note

This setup assumes that the repository server is reachable from your cloud infrastructure. If not, you need to provide a connection between the proxy and the repository server. If the repository server has an IP allow-list, the proxy can have a static IP assigned, and this IP can be added to the allow-list on the repository server side.

For detailed manual setup instructions, see the following guides:

Repository server within the VPC

If the repository server is located within the same cloud (for example, Azure DevOps in Azure cloud), the setup is less complex. You only need to pass the traffic from the Private Link Service to the repository server on HTTPS (port 443).

Architecture diagram showing Snowflake connecting through Private Link directly to a JFrog server within the same VPC.

Note

This diagram uses JFrog as an example. You can replace JFrog with any PyPI-compatible repository.

Step 2: Provision Private Endpoint

On the Snowflake side, you need to provision a Private Endpoint that reaches your infrastructure through a private IP.

When provisioning the Private Endpoint, you need to provide two arguments: the Private Link Service ID from your cloud provider and the repository server domain name.

Since Snowflake reaches your repository server through the HTTPS protocol, the domain name must have a valid certificate.

Note

Customer-hosted artifact repositories currently do not support self-signed certificates (not CA-signed).

Private Endpoint provision for AWS:

SELECT SYSTEM$PROVISION_PRIVATELINK_ENDPOINT(
  'com.amazonaws.vpce.us-west-2.vpce-svc-xxx',  -- VPC Endpoint Service Name
  'jfrog_address.com'                            -- Repository server domain
);

Private Endpoint provision for Azure:

SELECT SYSTEM$PROVISION_PRIVATELINK_ENDPOINT(
  '/subscriptions/9217bbdd-434e-4dbb-97c2-0825c627a277/resourceGroups/jfrog-server_group/providers/Microsoft.Network/privateLinkServices/jfrog-server-pl-service',  -- Private Service ID
  'jfrog_address.com'                                                                                                                                                -- Repository server domain
);

After the Private Endpoint is provisioned, you should see the awaiting Private Endpoint connection in your cloud Private Link Service. To finish the Private Endpoint setup, accept the connection request.

You can check the status of provisioning by calling the SYSTEM$GET_PRIVATELINK_ENDPOINTS_INFO system function. After you accept the Private Endpoint, the status field should change from:

  • AWS: Pending to Available
  • Azure: Pending to APPROVED
  • GCP: Pending to ACCEPTED

Step-by-step manual config for AWS (repository server outside of the VPC)

  1. Create and set up an EC2 proxy instance

    Create an EC2 instance with Amazon Linux that allows SSH traffic from your local machine. Make sure its Security Group allows inbound traffic on ports 22 (SSH) and 443 (HTTPS).

    Connect to the EC2 instance and install Docker:

    sudo yum install docker
    sudo service docker start
    

    Replace jfrog_address.com with your repository server domain and run:

    echo -e 'events {\n}\nstream {\n    upstream jfrog_server {\n        server jfrog_address.com:443;\n    }\n\n    server {\n        listen 443;\n        proxy_pass jfrog_server;\n    }\n}' > nginx.conf && \
    sudo docker run --rm -d --name my-custom-nginx-container \
      -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro \
      -p 443:443 nginx
    
  2. Create a Target Group for the EC2 proxy instance

    Create a Target Group that points to the EC2 instance (from the previous step) on TCP port 443.

  3. Create a Network Load Balancer

    Create a Network Load Balancer of type Internal in the same availability zone as the EC2 instance (for example, us-west-2b).

    If the Network Load Balancer operates in more than one zone (for example, us-west-2a and us-west-2b), enable the Cross-zone load balancing option so traffic from all zones goes to the EC2 instance.

    The load balancer should listen on TCP port 443 and forward traffic to the Target Group from the previous step.

  4. Create a VPC Endpoint Service

    Create a VPC Endpoint Service that sends traffic to the Network Load Balancer from the previous step.

    After creating the service, use the Service Name value for Step 2: Provision Private Endpoint.

Step-by-step manual config for Azure (repository server outside of the VPC)

  1. Create and set up a VM instance

    Create a VM instance with a VNet that allows SSH traffic from your local machine. Make sure network rules allow inbound traffic on ports 22 (SSH) and 443 (HTTPS).

    Connect to the VM instance:

    ssh -i ~/.ssh/id_rsa.pem username@IP-ADDRESS
    

    Install Docker (see Docker installation for Ubuntu) and start it:

    sudo service docker start
    

    Replace jfrog_address.com with your repository server domain and run:

    echo -e 'events {\n}\nstream {\n    upstream jfrog_server {\n        server jfrog_address.com:443;\n    }\n\n    server {\n        listen 443;\n        proxy_pass jfrog_server;\n    }\n}' > nginx.conf && \
    sudo docker run --rm -d --name my-custom-nginx-container \
      -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro \
      -p 443:443 nginx
    
  2. Create a Load Balancer

    The load balancer should listen on TCP port 443 and forward traffic to the VM from the previous step.

  3. Create a Private Link Service

    Create a Private Link Service that sends traffic to the Load Balancer from the previous step.

    After creating the service, use the ResourceID value for Step 2: Provision Private Endpoint.

Step-by-step manual config for GCP (repository server outside of the VPC)

  1. Create and set up a VM instance

    Create a VM instance with firewall rules that allow HTTPS (port 443) traffic.

    Connect to the VM instance, install Docker (see Docker installation for Ubuntu), and start it:

    sudo service docker start
    

    Replace jfrog_address.com with your repository server domain and run:

    echo -e 'events {\n}\nstream {\n    upstream jfrog_server {\n        server jfrog_address.com:443;\n    }\n\n    server {\n        listen 443;\n        proxy_pass jfrog_server;\n    }\n}' > nginx.conf && \
    sudo docker run --rm -d --name my-custom-nginx-container \
      -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf:ro \
      -p 443:443 nginx
    
  2. Add the VM to an instance group

    Create an unmanaged Instance Group that points to the created VM.

  3. Create a Load Balancer

    Create a Network Passthrough Internal Load Balancer with:

    • Backend configuration: TCP protocol with a health check set on port 443.
    • Frontend configuration: Receives traffic only on port 443.
  4. Create a Private Service Connect

    In the Private Service Connect section, publish a service that sends traffic to the Load Balancer from the previous step.

    Reserve a new subnet for your service, or use an existing one. Either automatically accept connections or define projects that will be accepted. Snowflake’s project ID can be retrieved from the result of calling:

    SELECT SYSTEM$GET_PRIVATELINK_CONFIG();
    

    After creating the service, use the Service attachment field for Step 2: Provision Private Endpoint.

Troubleshooting

Most artifact-repository failures fall into one of a few patterns: a missing entry in API_ALLOWED_PREFIXES, incorrect credentials in the SECRET, or a package that the upstream repository cannot serve. The HTTP status code in the error message is usually the strongest diagnostic signal. Start with the status-code table below, then run one or more of the four reproduction steps to confirm and narrow down the root cause. If you still need help, the last section lists what information to provide when you contact Snowflake support.

General guidelines:

  • 5xx errors almost always indicate a Snowflake-side issue.
  • 401 / 403 errors almost always indicate a repository-side issue.
  • 400 errors almost always indicate a missing entry in API_ALLOWED_PREFIXES.

HTTP status code reference

HTTP statusWhat it usually meansFirst thing to try
400 Bad RequestSnowflake. The URL Snowflake is about to fetch is not in API_ALLOWED_PREFIXES. Most often the wheel URL listed in your repo’s simple-index page points to a CDN/blob host (CloudFront for JFrog Cloud, a CDN host for Azure DevOps Artifacts, S3 for Sonatype Nexus) that isn’t in your allowlist. Look for error code: 10003.Repro #3 to capture every host involved, then add the missing host(s) to API_ALLOWED_PREFIXES.
401 UnauthorizedRepository-side. The credentials in your SECRET are not authenticating against your upstream repository.Repro #2 with the same credentials. If curl also fails, recreate the secret. If curl succeeds but Snowflake still returns 401 — particularly with the message Authentication failed. Please check your credentials. — contact Snowflake support.
403 ForbiddenEither side. (a) Your upstream repository is blocking that specific package or version (Nexus quarantine, Azure DevOps ACL, JFrog rule). (b) The same API_ALLOWED_PREFIXES problem as 400, but caught later: Snowflake began fetching from an allowed URL and the repository redirected (3xx) to a host that is not in the allowlist.Repro #2 against the failing URL. If curl returns 403, the issue is on the repository side — contact your repository administrator. If curl succeeds, run Repro #3 to find the redirect target you need to add to API_ALLOWED_PREFIXES.
404 Not FoundEither. (a) Your ARTIFACT REPOSITORY object doesn’t exist on this account, or your role lacks USAGE on it. (b) The package is blocked by the repository’s package policy (blocked packages deliberately appear non-existent). (c) The package/version genuinely doesn’t exist on your upstream.Repro #1 to rule out (a) and (b). If those are clean, run Repro #2 and confirm the package is listed in the simple-index page.
422 Unprocessable EntitySnowflake. Internal request-validation error. You should not normally see this.Capture the query ID and contact Snowflake support.
500 Internal Server ErrorSnowflake in nearly every case. JFrog and Nexus rarely emit 500s in practice.Retry. If it persists, run Repro #4 to capture a clean query ID and contact Snowflake support.
502 Bad GatewaySnowflake. Snowflake could not reach your upstream repository — DNS resolution failed, TLS handshake failed, the connection timed out, the redirect chain exceeded 20 hops, or the repository returned an unparseable Location header.Repro #2 from a workstation. If curl succeeds, the repository is reachable from the public Internet but Snowflake cannot reach it — contact Snowflake support with the query ID. For PrivateLink setups, see the PrivateLink section below.
503 Service UnavailableSnowflake. Transient backend condition. JFrog and Nexus rarely emit 503 errors.Retry after a minute. If the error persists across multiple retries, contact Snowflake support.
Unable to connect to the artifact repository server. 'null'Snowflake. Transient internal connectivity issue. There is typically no query ID attached.Retry. If the error persists, contact Snowflake support with the timestamp and your account locator.

Repro #1 — Verify your Snowflake setup

Run this first. It confirms your four Snowflake objects (secret, API integration, artifact repository, and grants) are wired up correctly, and rules out the simplest causes — including both branches of the 404 row.

SHOW ARTIFACT REPOSITORIES;
SHOW GRANTS ON ARTIFACT REPOSITORY <your_repo>;

DESCRIBE SECRET <your_secret>;
DESCRIBE INTEGRATION <your_api_integration>;
DESCRIBE ARTIFACT REPOSITORY <your_repo>;

SELECT SYSTEM$GET_ARTIFACT_REPOSITORY_INFO('<your_repo>');

Confirm:

  • SHOW GRANTS shows USAGE on the artifact repository for the role that runs the UDF / stored procedure.
  • DESCRIBE INTEGRATION shows API_PROVIDER = ARTIFACT_REPOSITORY_API, ENABLED = TRUE, your secret in ALLOWED_AUTHENTICATION_SECRETS, and every host from Repro #3 in API_ALLOWED_PREFIXES.
  • DESCRIBE ARTIFACT REPOSITORY shows an INDEX_URL ending in /simple/, pointing at a host that is in API_ALLOWED_PREFIXES, with AUTHENTICATION_SECRET set to the same secret as on the API integration.
  • SYSTEM$GET_ARTIFACT_REPOSITORY_INFO shows the same view, plus the current packages_policy_json if you have a package policy configured (which can cause 404 on blocked packages).

If this did not resolve the issue, include the output of all of the commands above (with the secret password redacted — DESCRIBE SECRET does not display it, but double-check) when you contact Snowflake support.

Repro #2 — Test your repo’s auth from outside Snowflake

Use this when you suspect an authentication or connectivity problem (typically a 401, 403, 404, or 502 in the table above). The idea is to send the same Authorization header Snowflake would send, from a machine that can reach your repo. For PrivateLink-only repositories, run these commands from a machine within your VPC that can reach the repository endpoint. Two styles, depending on which TYPE your SECRET uses.

Style A — TYPE = PASSWORD (username + password or PAT). This is the typical pattern for JFrog Cloud, Sonatype Nexus, and Azure DevOps Artifacts. The PAT goes in the PASSWORD field even though it isn’t a literal password. Snowflake sends Authorization: Basic base64(USERNAME:PASSWORD) — exactly what curl -u "USERNAME:PASSWORD" does.

CREATE SECRET my_repo_secret
  TYPE = PASSWORD
  USERNAME = 'jdoe@example.com'
  PASSWORD = 'AKCp1AB...redacted...XYZ';
curl -i -u "jdoe@example.com:AKCp1AB...redacted...XYZ" "<INDEX_URL><package>/"

Style B — TYPE = GENERIC_STRING (single opaque token). Use this when your repo expects a single token with no separate username — the form pip configures as https://<token>@<host>/simple/. Snowflake sends Authorization: Basic base64(SECRET_STRING).

CREATE SECRET my_repo_secret
  TYPE = GENERIC_STRING
  SECRET_STRING = 'AKCp1AB...redacted...XYZ';
curl -i "https://AKCp1AB...redacted...XYZ@<host>/<index-path>/<package>/"

Note

Redact your credentials before sharing the command or its output with anyone, including Snowflake support.

Interpret what curl returns:

  • HTTP 200 + a list of wheels — auth is good. Move to Repro #3.
  • HTTP 401 — your secret is wrong, the password/PAT has expired, or your repo expects a different username format (some repos want an email, some want an account name, some want the literal string oauth2). Recreate the secret with ALTER SECRET ... SET ....
  • HTTP 403 — you can reach the repository but it is refusing to serve this package or path. Contact your repository administrator (quarantine, ACL).
  • Connection refused / timeout — network or firewall problem, not auth.

If this did not resolve the issue, include the exact curl command (with credentials redacted), the HTTP status it returned, and the first ~20 lines of the response body (also redacted) when you contact Snowflake support.

Repro #3 — Capture every host the install actually touches

Use this when the table or Repro #2 points at API_ALLOWED_PREFIXES — typically a 400 Bad Request (error code: 10003) or a 403 you confirmed isn’t from your repo.

On a clean Python virtualenv, reproduce the install with the same INDEX_URL Snowflake uses and ask pip to print everything it does:

python -m venv /tmp/repro && source /tmp/repro/bin/activate
pip install --dry-run -vvv \
  --index-url "https://<user>:<token>@<host>/<index-path>/" \
  <package>==<version>

If you’d rather use curl, the equivalent is to follow redirects on a wheel URL and print every hop:

curl -L -i -u "<user>:<token>" "<wheel-url-from-the-index-page>"

List every distinct host that appears in the output — the index host, the wheel/blob host, any CDN redirect target. Every one of those hosts must be in API_ALLOWED_PREFIXES on your API INTEGRATION.

Examples of hosts that are commonly missed:

  • JFrog Cloud — <tenant>.jfrog.io and a *.cloudfront.net host.
  • Azure DevOps Artifacts — pkgs.dev.azure.com and a separate CDN/blob host for downloads.
  • Sonatype Nexus with S3 blob storage — the Nexus host and the S3 host.

If this did not resolve the issue, include the full list of distinct hosts you observed (or the verbose pip output, with credentials redacted), and the current value of API_ALLOWED_PREFIXES from DESCRIBE INTEGRATION when you contact Snowflake support.

Repro #4 — Smallest possible repro inside Snowflake

Use this once Repro #2 and Repro #3 have confirmed your repository is reachable and configured. The goal is a clean, isolated query_id that Snowflake support can trace.

CREATE OR REPLACE FUNCTION repro_install()
  RETURNS STRING
  LANGUAGE PYTHON
  RUNTIME_VERSION = '3.10'
  ARTIFACT_REPOSITORY = <your_repo>
  PACKAGES = ('<single_package>==<version>')
  HANDLER = 'run'
AS $$
def run(): return "ok"
$$;

SELECT repro_install();
SELECT LAST_QUERY_ID();

Tips:

  • Test packages one at a time. If setuptools is blocked upstream, every install will look broken.
  • Try a different RUNTIME_VERSION (3.9, 3.10, 3.11) — wheels often exist for one Python version but not another.

If this did not resolve the issue, include the failing UDF SQL, the query_id from SELECT LAST_QUERY_ID();, and the full untruncated error message when you contact Snowflake support.

Other common pitfalls

  • Upstream-side blocks (quarantine, ACL). Your repository can refuse to serve specific packages or versions — Nexus quarantine, Azure DevOps ACLs, JFrog repository rules. Snowflake surfaces these as HTTP 403 errors. Confirm with your repository administrator.
  • Snowflake-side package policy blocks. If your ARTIFACT REPOSITORY has a package allow/deny policy, blocked packages return 404 (not 403) — they deliberately look as if they don’t exist.
  • Pinning around blocked transitive deps. If an indirect dep (e.g. setuptools<82) is blocked, pin around it: PACKAGES = ('mypkg==1.2', 'setuptools<82').
  • Python runtime mismatch. Wheels exist for 3.10 but not 3.11 (or vice versa). Try the other runtime.
  • Trailing slash on INDEX_URL. pip cares about the trailing /simple/. Re-paste the URL from DESCRIBE and visually check it.
  • Token rotated on your side. Update the secret with ALTER SECRET ... SET PASSWORD = '<new>' (re-test with Repro #2 first).
  • Embedded credentials in INDEX_URL. Not allowed. Use a SECRET.
  • Handler / file-naming typos. The package may install fine and the real failure is ModuleNotFoundError for your code, not the package.

When you contact Snowflake support

If the steps above have not resolved the issue, submit a support case and provide as much of the following information as possible:

  • Your account locator and region.
  • The query_id from the failing call (SELECT LAST_QUERY_ID(); right after the failure).
  • The full error message — do not truncate. The upstream URL embedded in the error is the most diagnostic single piece of information.
  • DDL of the SECRET (with PASSWORD redacted), the API INTEGRATION, and the ARTIFACT REPOSITORY, exactly as DESCRIBE returns them.
  • Output of SELECT SYSTEM$GET_ARTIFACT_REPOSITORY_INFO('<repo>');.
  • Output of SELECT SYSTEM$GET_PRIVATELINK_ENDPOINTS_INFO(); if you’re using PrivateLink.
  • The exact curl and pip install commands you ran in Repros #2 and #3, with credentials redacted, and their outputs.
  • Repository platform and edition (JFrog Cloud, JFrog self-hosted, Sonatype Nexus, Azure DevOps Artifacts, GCP Artifact Registry, AWS CodeArtifact, other).
  • Whether the connection is over the public Internet or PrivateLink.