"Couldn't load the external resource" error with S3 pre-signed URL

Hi, I am using Neo4j via docker and I got the following problem when using MinIO Pre-Signed URLs to load csv, both using apoc and load csv

I am using neo4j:2025.06.2

And I am using Docker compose

I added the arguments needed to take the proxy config into consideration

I am able to:

  • Use n10s with presigned urls
  • Use load csv with local files
  • Use load csv with http and https urls
  • Use apoc to load csv with the s3://bucket/object urls
  • Use apoc to load csv with http and https urls

However when I use:

CALL apoc.load.csv("<pre-signed url>")

I get:

Neo.ClientError.Procedure.ProcedureCallFailed
Failed to invoke procedure `apoc.load.csv`: Caused by: java.io.IOException: Server returned HTTP response code: 403 for URL:<pre-signed url>

And when I use:

LOAD CSV WITH HEADERS FROM "<pre-signed url>"

I get:

Neo.ClientError.Statement.ExternalResourceFailed
Cannot load from URL "<pre-signed url>" Couldn't load the external resource at: <pre-signed url>

And to double check, I ran curl “<pre-signed url>” from inside the neo4j container and it was accessible.

I appreciate your help!

Is your configuration:


dbms.security.procedures.unrestricted=apoc.* 
apoc.import.file.enabled=true
apoc.import.file.use_neo4j_config=false

Hi, it is like this:

NEO4J_dbms_security_allow__csv__import__from__file__urls: true
NEO4J_apoc_export_file_enabled: true
NEO4J_apoc_import_file_enabled: true
NEO4J_apoc_import_file_use__neo4j__config: true
NEO4J_dbms_security_procedures_unrestricted: apoc.*,n10s.*
NEO4J_dbms_security_procedures_allowlist: apoc.*,n10s.*

and I made sure that the server.directories.import=import is commented in the neo4j.conf file

Try testing by bypassing SSL:

CALL apoc.load.csv(url, {header: true, config: {failOnError: false}}) 

Same error:

Neo.ClientError.Procedure.ProcedureCallFailed
Failed to invoke procedure `apoc.load.csv`: Caused by: java.io.IOException: Server returned HTTP response code: 403 for URL

Also I got an ssl problem only with s3://… URIs and fixed it using:

NEO4J_server_jvm_additional: -Dcom.amazonaws.sdk.disableCertChecking=true

My last idea:

CALL apoc.load.csvStream(url, {header: true}) 
YIELD map, lineNo 
RETURN map, lineNo 
LIMIT 5

I can’t find csvStream, I am getting Neo.ClientError.Procedure.ProcedureNotFound error

And I have apoc and apoc-extended plugins

Just a guess, but I think the problem is related to the noProxy argument

Because the procedure works with public http and https and doesn’t work only with the pre-signed url that uses http://minio:9000/…

However the pre-signed url http://minio:9000/… works perfectly with n10s plugin

So I am not sure if there are specific arguments for the apoc plugin to specify the noProxy argument

OK … maybe it was removed from apoc. Not sure what can be done as this is an error on the server side, do you need to run this often? why don’t you download the files and run them locally?

The 403 (Forbidden) status code indicates that the server understood the request but refuses to fulfill it. A server that wishes to make public why the request has been forbidden can describe that reason in the response content (if any).

If authentication credentials were provided in the request, the server considers them insufficient to grant access. The client SHOULD NOT automatically repeat the request with the same credentials. The client MAY repeat the request with new or different credentials. However, a request might be forbidden for reasons unrelated to the credentials.

I got it working with local files but for my use case I do need to use the pre-signed URLs.

Thanks for sharing this doc, it clarifies the meaning of the error, but since it’s a pre-signed url and it is accessible through curl inside the neo4j container, logically it is not a credentials problem.

So that is way I thought that it might be a problem caused by the proxy.

1 Like

:black_large_square: :white_check_mark: -- Solved 1 of the 2 errors -- The apoc.load.csv error

The problem was that the pre-signed url was using the http://minio:9000/… address but the apoc procedure was changing it to the corresponding docker network ip, e.g. http://127.18.0.8:9000/… which made the pre-signed url no longer accessible

So the solution is to fix the minio ipv4 address and use it as pre-signed endpoint, and for my case I had to specify it in the nonProxyHosts argument too

However I still get the same error for the LOAD CSV FROM "<pre-signed url>" method

It looks to me that your docker might have some DNS configuration problems then … and somehow Neo4J’s daemon is not picking it up.